Switch to using pillow for png as well.#15193
Conversation
bcd1d5d to
f41b156
Compare
tacaswell
left a comment
There was a problem hiding this comment.
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.
Doesn't the condition mean this function should be removed?
There was a problem hiding this comment.
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.
That's not what the removed code says.
There was a problem hiding this comment.
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): |
| 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.
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.
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.
Just style but rather:
data = output.view(dtype=np.uint8).reshape((*output.shape, 4))
Image.fromarray(data).save(buf, format="png")
| 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.
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.
Please adapt to the new way of documentation API changes.
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).
timhoffm
left a comment
There was a problem hiding this comment.
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