-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Switch to using pillow for png as well. #15193
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
Conversation
bcd1d5d
to
f41b156
Compare
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.
Modulo the 16bit read-back being document as an API change.
Looks good to me, in general terms. |
API change note about precision loss added. |
return self._print_image(filename, wx.BITMAP_TYPE_JPEG, | ||
*args, **kwargs) | ||
print_jpg = print_jpeg | ||
def print_jpeg(self, filename, *args, **kwargs): |
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.
Doesn't the condition mean this function should be removed?
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.
no, the wx backend (not wxagg!) has always relied on wx's native handling of png/tiff/jpeg/...
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.
That's not what the removed code says.
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.
If I understand this correctly, @QuLogic is right, but the API change is now documented.
return self._print_image(filename, wx.BITMAP_TYPE_TIF, | ||
*args, **kwargs) | ||
print_tif = print_tiff | ||
def print_tiff(self, filename, *args, **kwargs): |
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.
And this one too.
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.
as above
return pil_to_array(image) | ||
from matplotlib import _png | ||
img_open = ( | ||
PIL.PngImagePlugin.PngImageFile if ext == 'png' else PIL.Image.open) |
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.
Do we even need this, or can we just do everything through plain open
? (I understand that the _pil_png_to_float_array
bit is for backwards compatibility.)
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.
No, the point is to force pillow to open the image as png if ext == "png"
, regardless of what pillow may think the image is.
113fbe9
to
9f9f93f
Compare
rebased |
3a7407b
to
f0bcdff
Compare
buf = BytesIO() | ||
(Image.fromarray( | ||
output.view(dtype=np.uint8).reshape((*output.shape, 4)) | ||
.save(buf, format="png"))) |
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.
Just style but rather:
data = output.view(dtype=np.uint8).reshape((*output.shape, 4))
Image.fromarray(data).save(buf, format="png")
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.
done
return self._print_image(filename, wx.BITMAP_TYPE_JPEG, | ||
*args, **kwargs) | ||
print_jpg = print_jpeg | ||
def print_jpeg(self, filename, *args, **kwargs): |
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.
If I understand this correctly, @QuLogic is right, but the API change is now documented.
@@ -0,0 +1,10 @@ | |||
Matplotlib now uses Pillow to save and read pngs |
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.
Please adapt to the new way of documentation API changes.
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.
done
The version check in _has_pil (pillow>=3.4) was dropped as the oldest Pillow that supports Py3.6 (the oldest Python supported by Matplotlib) is 4.0 anyways. Some complications arise from an unfortunate design decision that imread() returns pngs in 0-1 float dtype but others formats in integer dtype (via Pillow), and from Pillow having not-so-great support for 16-bit images (e.g. Pillow#3041). This makes reading of 16-bit RGB(A) PNGs (which are exposed as 0-1 floats by imread()) slightly less accurate, because Pillow coarsens them to 8-bit first (by truncation); hence the slight change in the pngsuite.png baseline image. (Note that the *renderers* only have 8-bit precision anyways (unless using mplcairo with cairo master...), but the discrepancy comes from differences in rounding between Pillow and Matplotlib).
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.
Anybody can merge after CI pass.
self-merging per the above. |
PR Summary
Closes #15165.
Probably needs discussion as to whether the loss of precision for reading 16-bit RGB(A) pngs is a blocking issue or not.
The version check in _has_pil (pillow>=3.4) was dropped as the oldest
Pillow that supports Py3.6 (the oldest Python supported by Matplotlib)
is 4.0 anyways.
Some complications arise from an unfortunate design decision that
imread() returns pngs in 0-1 float dtype but others formats in integer
dtype (via Pillow), and from Pillow having not-so-great support for
16-bit images (e.g. Pillow#3041).
This makes reading of 16-bit RGB(A) PNGs (which are exposed as 0-1
floats by imread()) slightly less accurate, because Pillow coarsens them
to 8-bit first (by truncation); hence the slight change in the
pngsuite.png baseline image. (Note that the renderers only have 8-bit
precision anyways (unless using mplcairo with cairo master...), but the
discrepancy comes from differences in rounding between Pillow and
Matplotlib.)
I have a followup PR that makes it possible to build Matplotlib on Windows on a clean python.org python with just MSVC installed (by setting MPLLOCALFREETYPE=1).
Edit: This previously depended on #15175, but is now independent of it.
PR Checklist