python-pillow / Pillow

Python Imaging Library (Fork)
https://python-pillow.org
Other
12.27k stars 2.23k forks source link

Raw formats (DNG, GPR, NEF) #6482

Open gverm opened 2 years ago

gverm commented 2 years ago

What did you do?

I opened the images using Pillow and printed their detected size.

What did you expect to happen?

The size to be reported correctly. This causes conversions to JPEG to be way too small.

What actually happened?

Size was reported incorrectly.

What are your OS, Python and Pillow versions?

>>> from PIL import Image
>>> img = Image.open("sample.dng")
>>> img.width, img.height
(256, 195)
>>> img = Image.open("sample2.NEF")
>>> img.width, img.height
(160, 120)

Interestingly the file command also shows the wrong sizes:

$ file sample.dng
sample.dng: TIFF image data, little-endian, direntries=60, height=195, bps=734, compression=none, PhotometricIntepretation=RGB, manufacturer=NIKON CORPORATION, model=NIKON Z 7, orientation=upper-right, width=256

$ file sample2.NEF
sample2.NEF: TIFF image data, little-endian, direntries=28, height=120, bps=352, compression=none, PhotometricIntepretation=RGB, manufacturer=NIKON CORPORATION, model=NIKON D7200, orientation=upper-left, width=160

While inspecting the files with Dolphin shows the correct sizes: image

sample.dng sample2.NEF

radarhere commented 2 years ago

When I inspect the image with exiftool -v, I see that sample2.NEF has an image that is 160x120.

However, I also see that it has child images - two reduced resolution images, called JpgFromRaw and OtherImage, and one full resolution image that is 6016x4016.

So I don't know that Pillow is necessarily doing anything wrong. Would you like to instead request that Pillow provide an API to access those child images?

gverm commented 2 years ago

However, I also see that it has child images - two reduced resolution images, called JpgFromRaw and OtherImage, and one full resolution image that is 6016x4016.

That's interesting, I didn't know about that, thanks for explaning.

So I don't know that Pillow is necessarily doing anything wrong. Would you like to instead request that Pillow provide an API to access those child images?

That would be great.

kmilos commented 2 years ago

I guess Pillow only ever tries to access the root IFD (IFD0) of a TIFF-based file, and that's a sensible assumption IMHO.

For most camera raw images, the root IFD is the JPEG thumbnail (I guess it makes it easy for image viewers and file managers to access as well).

If you want to work w/ camera raw images, you're much better of working w/ rawpy or tifffile directly rather than extending Pillow for this specialized case...

radarhere commented 2 years ago

It turns out that even with support for child images, the files provided here fail to load.

sample.dng has five child images. One of the child images fails to load with

  File "/PIL/TiffImagePlugin.py", line 1426, in _setup
    self.mode, rawmode = OPEN_INFO[key]
KeyError: (b'II', 32803, (1,), 1, (16,), ())

and three fail with because Pillow does not currently support Lossy JPEG compression.

  File "PIL/TiffImagePlugin.py", line 1355, in _setup
    self._compression = COMPRESSION_INFO[self.tag_v2.get(COMPRESSION, 1)]
KeyError: 34892

sample2.NEF has 3 child images. One of them fails because Pillow does not currently support Nikon NEF compression.

  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/PIL/TiffImagePlugin.py", line 1352, in _setup
    self._compression = COMPRESSION_INFO[self.tag_v2.get(COMPRESSION, 1)]
KeyError: 34713
radarhere commented 2 years ago

I've created PR #6569 to add reading of TIFF child images.

AhmedAldahshoury commented 1 year ago

Even with get_child_images(), it fails to load a NEF image.

self._compression = COMPRESSION_INFO[self.tag_v2.get(COMPRESSION, 1)]

radarhere commented 1 year ago

3962 has a request for a related format - GPR.

https://github.com/gopro/gpr

The General Purpose Raw (GPR) is 12-bit raw image coding format that is based on Adobe DNG® standard

radarhere commented 1 year ago

7487 requests support for LinearRaw Photometric Interpretation, part of the DNG specification.