-
-
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
Saving 16-bit grayscale PNG image doesn't work #6997
Comments
https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#png-saving states that
So, yes, it should be compressed. You are generating random numbers, which sounds like the the nightmare scenario when trying to compress data.
There is an open issue for this - #3796. If you are looking for an explanation, I can offer #3041 (comment)
For one thing, Pillow doesn't have a mode that corresponds to every NumPy mode. We have For another, the PNG format has a maximum of 16 as the bit depth - http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html. So even if we added a mode for unsigned 32-bit integers, it wouldn't made sense to request that the PNG be opened as such.
The 16-bit image has values that range from 0-65534 and the 32-bit image has values that range from 0-2147473565. It seems reasonable to think that the PNG found a way to turn the smaller amount of information into a smaller file. If I turn off the compression by replacing |
@radarhere
I see, so when 32-bit uint array is saved as PNG all values above 2**16-1 are simply discarded (set to zero?) which reduces the information in This is perhaps a better showcase of the compression using a checkerboard: import numpy as np
from PIL import Image
import os
maxuint = {
'uint16':2**16-1,
'uint32':2**32-1
}
imgs = []
for dtyp in ['uint16', 'uint32']:
for ext in ['tif', 'png']:
maxval = maxuint[dtyp]
#o = np.random.rand(1470,50)
o = np.zeros((1470, 50))
o[::10] = 0.5
o[:,::10] = 1
o = o*maxval
o = o.astype(dtyp)
im = Image.fromarray((o))
name = f'test-{dtyp}.{ext}'
im.save(name, compress_level=1)
im = Image.open(name)
a = np.asarray(im)
size = os.stat(name).st_size
print(f'{name}: {a.shape} {a.dtype} {size:,} Max:{a.max()}')
imgs.append(im)
print('- '*3)
for im in imgs:
display(im)
Output:
The tiff can still not be saved as uint32, max is not 2**32-1 and the vertical stripes in the checkerboard are gone? |
I now think you're talking about #3159
As I said,
You might be interested in the F mode - https://pillow.readthedocs.io/en/stable/handbook/concepts.html#modes
The vertical stripes aren't gone in the saved TIFF files, only when they are opened and shown - Pillow saves images to be shown as temporary PNG files. |
@radarhere Thank you! |
Hi!
I'm trying to wrap my head around this, I read some issues have been fixed, but perhaps there still are some problems:
#2970
#3566
I'm trying to save a grayscale PNG image with compression, either uint16 or uint32, steps to reproduce:
Output:
Expected behaviour:
test-uint16.png
should load as uint16test-uint32.tif
andtest-uint32.png
should load as uint32The text was updated successfully, but these errors were encountered: