-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Delegate Image mode and size to ImagingCore #7271
Conversation
There is a |
Could you provide an explanation for why this change is helpful? |
I think keeping the mode and size of |
As this PR knows, because
I agree, and I would think that they are already in sync.
While this PR isn't yet finalised, it would seem that the idea here is to make Python's |
The original issue that I created this change for was discussed here: #7260 (comment) The problem was that changing an image's mode in C does not change the mode seen in Python, because the C code doesn't have access to the Python value. So if an image's mode or size is ever changed directly in C, it will be out of sync with the value(s) in Python. Likewise, if one of these values is changed in Python, it will be out of sync with the value(s) in C (making |
Pillow has a public Python API. Our intention is not for users to access the C API directly. If
I think ignoring the Python mode would obscure the fact that in this scenario, setting the mode in Python is not having the intended effect. That doesn't sound helpful to me.
It ensures that |
This is currently the case. Before #7307 (which is not yet part of a release), it was possible to set
|
If you'd like to wait until #7260 is resolved, okay.
When I said this, I wasn't referring to setters for mode, I was referring to |
|
…ilable When setting the values on Image also try to update the values on Image.im. There isn't currently a way to update values in the other direction.
e311a46
to
919dbbe
Compare
New change based on main.
If |
and use double quotes instead of single quotes
def6e62
to
b879ada
Compare
@@ -139,6 +139,9 @@ def get_format_mimetype(self): | |||
if self.format is not None: | |||
return Image.MIME.get(self.format.upper()) | |||
|
|||
def _use_im_values(self): | |||
return self.tile is None and self.im is not None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is purpose of self.tile
check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@radarhere proposed that change for ImageFile
in a pull request they made for the previous code. The issue is that when seeking to another frame, the Image
values may not match the Image.im
values. Using not self.tile
like in their pull request wasn't working for me though, so I changed it to self.tile is None
, which after looking into it more, probably isn't correct.
self->image->xsize = xsize; | ||
self->image->ysize = ysize; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why we want to do this? It will just break image
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So that if Image.size
is changed, Image.im.size
will have the same value. Another option could be that if Image.size
is changed, and Image.im.size
doesn't match, it raises an exception.
if self._use_im_values(): | ||
return self.im.size | ||
return self.__size |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this can't be just in size
property?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The _size
getter is actually used in quite a few places, so that would have to be changed to use the size
getter first. It would save three lines if the _size
getter was removed though:
@property
def size(self):
if self._use_im_values():
return self.im.size
return self.__size
def _size(self, value):
# set im.size first in case it raises an exception
if self._use_im_values():
self.im.size = value
self.__size = value
_size = property(fset=_size)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would save three lines
More important that this saves one indirect method call (width → size → _size) on each attribute getter.
As far as I can see, Yay295#8 removed the need for I'm not in favour of this PR, for reasons stated earlier. @homm you've left some individual comments, but regarding the basic idea, do you see value here that I don't? Part of the reason I mention this now is that I see pydicom/pydicom#1907 referencing this in trying to grapple with #7307, and that doesn't seem helpful. I know that this PR is unmerged and in draft mode, so it has all the indications that it is not ready for consumption, but nevertheless. |
I do see profit in wall-time and memory consumption, but I'm not sure about public interface. In general, I think we can close it for now. |
This causes a lot of errors. The main issues are that
Image.im
isn't always set, so we still need to keep Python-only variables for these properties, and the Python values are writable, but the C values are not writable from Python.