-
-
Notifications
You must be signed in to change notification settings - Fork 287
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
New behavior of imageio.imsave #1020
Comments
Interesting. Afaik JPEG only supports 8-bit depth, so saving 16-bit JPEG sounds a bit surprising; did you verify that you actually save in 16-bit and don't internally convert to 8-bit before saving? I get the same exception when I try to save a 16-bit array ( >>> import imageio.v3 as iio
>>> import numpy as np
>>> img = iio.imread("imageio:chelsea.png")
>>> img = img.astype(np.uint16)
>>> iio.imwrite("foo.jpeg", img)
Traceback (most recent call last):
File "/Users/sebastian.wallkotter@schibsted.com/projects/imageio/.venv/lib/python3.10/site-packages/PIL/Image.py", line 3070, in fromarray
mode, rawmode = _fromarray_typemap[typekey]
KeyError: ((1, 1, 3), '<u2')
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/sebastian.wallkotter@schibsted.com/projects/imageio/imageio/v3.py", line 147, in imwrite
encoded = img_file.write(image, **kwargs)
File "/Users/sebastian.wallkotter@schibsted.com/projects/imageio/imageio/plugins/pillow.py", line 416, in write
pil_frame = Image.fromarray(frame, mode=mode)
File "/Users/sebastian.wallkotter@schibsted.com/projects/imageio/.venv/lib/python3.10/site-packages/PIL/Image.py", line 3073, in fromarray
raise TypeError(msg) from e
TypeError: Cannot handle this data type: (1, 1, 3), <u2 However, I think this behavior is a desirable default because the alternative (a silent downcast) loses quality in a hard to detect way. Granted, for JPEG specifically this isn't to big an issue since compression affects quality much more. I think there is value in having consistent defaults across commonly used formats on this behavior, though we could view it as a regression and bring it back for JPEG specifically if you feel strongly about it.
The implicit conversion was done via Lines 45 to 108 in 3dd6574
How did you verify that the result "is similar but not exactly the same"? |
Hi, thanks for your feedback. This is my code: with rawpy.imread(in_filename) as raw:
rgb = raw.postprocess(gamma=(1, 1), no_auto_bright=False, output_bps=16)
image.imsave(out_filename, rgb) I checked that in both my environments (with different versions of the various dependencies), the My code is now: with rawpy.imread(in_filename) as raw:
rgb = raw.postprocess(gamma=(1, 1), no_auto_bright=False, output_bps=16)
rgb = (rgb >> 8).astype(np.uint8)
image.imsave(out_filename, rgb) I checked whether the output RGB images in 2.15 vs. 2.31.1 would be the same by simply (and crudely) comparing the mean pixel intensities in a series of small patches of the images generated by Thanks! |
Odd that your tests fail. When I write a JPEG with either version I get identical results: >>> import imageio
>>> import numpy as np
>>> imageio.__version__
'2.15.0'
>>> img = 4*imageio.imread("imageio:chelsea.png").astype(np.uint16)
>>> imageio.imwrite("imageio-2-15-0.jpeg", img)
Lossy conversion from uint16 to uint8. Losing 8 bits of resolution. Convert image to uint8 prior to saving to suppress this warning. >>> import imageio
>>> import numpy as np
>>> import imageio.v3 as iio
>>> imageio.__version__
'2.31.1'
>>> img = 4*iio.imread("imageio:chelsea.png").astype(np.uint16)
>>> iio.imwrite("imageio-2-31-1.jpeg", (img >> 8).astype(np.uint8))
>>> img1 = iio.imread("imageio-2-31-1.jpeg")
>>> img2 = iio.imread("imageio-2-15-0.jpeg")
>>> np.all(img1==img2)
True |
Maybe However, I also noticed in your code that in version 2.15.0, Anyhow, I'll investigate further when I am back. Thanks! |
No, I didn't remove any warning. The code for |
Hi,
in an old code base, we used
imsave()
fromimageio
version 2.15.0 to save 3-channel, 16-bit arrays to RGB JPEGs.imageio.imsave()
would take care of the conversion for us. I am now porting the code to use more recent versions of several libraries, and among those we now useimageio
version 2.31.1. Our code now fails withTypeError: Cannot handle this data type: (1, 1, 3), <u2
when passing the 3-channel, 16-bit array toimsave()
.I tentatively added a simple conversion to 8-bit before saving:
rgb = (rgb >> 8).astype(np.uint8)
and the result is very similar to what
imageio
2.15.0 would create, but not exactly the same.Would it be possible to know (a pointer to the code would be enough, I guess) how the 2.15.0 version of
imsave()
was converting the 3-channel, 16-bit image to 8-bit RGB?I tested with both Pillow version 8.4 and 10.0, and the result is the same.
Thanks!
The text was updated successfully, but these errors were encountered: