Closed marcuskammer closed 4 years ago
This was discussed on IRC last month, and it was determined to be caused by EXIF metadata in the photos: (not really, see post below)
I did some debugging. The images that fail to be processed are detected as<class 'PIL.MpoImagePlugin.MpoImageFile'>
with is_animated = True, n_frames = 2
. Nikola refuses to resize animated images.
I’m not sure where to go from there and what we should do to those files.
Wow, thank you for your debugging. How can these images be classified as animated
? Their are just regular jpegs, straight copied from my camera?! I did check the exif metadata with exiv2 and could not find any information about animation
. Maybe it is a bug in the Python Lib Pillow? I will play around with Pillow.
I did check the jpeg standard. https://en.wikipedia.org/wiki/JPEG_File_Interchange_Format
It is allowed to embed a thumbnail image into the Exif metadata of a jpeg image. Many camera producers do this to allow a preview of the image. The related exif metadata are Exif.Thumbnail.*
. Because of this, PILLOW identifies these images as Multi Picture Object and not as JpegImageFile
.
I also did check image_processing.py
:
def resize_image(self, src, dst, max_size, bigger_panoramas=True, preserve_exif_data=False, exif_whitelist={}, preserve_icc_profiles=False):
"""Make a copy of the image in the requested size."""
if not Image or os.path.splitext(src)[1] in ['.svg', '.svgz']:
self.resize_svg(src, dst, max_size, bigger_panoramas)
return
im = Image.open(src)
if hasattr(im, 'n_frames') and im.n_frames > 1:
# Animated gif, leave as-is
utils.copy_file(src, dst)
return
It checks if the image has more than one frame. And of course it has 2 frames, the original image and the embedded thumbnail image. But it is wrong to suggest a image is of type GIF if the frame count is greater than 1?!
Pillow also says that this image is_animated
, although we don’t check that attribute. I think we could override this check for MPO/JPEG-with-thumbnail files, but you should perhaps report this issue with is_animated/n_frames
directly to Pillow (https://github.com/python-pillow/Pillow/issues).
I do not know the intention of if hasattr(im, 'n_frames') and im.n_frames > 1:
but as the comment line suggests, it should check if the image is of type Gif. I would suggest the use of isinstance instead of hasattr. e.g.:
from PIL.GifImagePlugin import GifImageFile
if isinstance(im, GifImageFile):
...
The current implementation has an issue with your images, but handles two other cases correctly: (a) non-animated GIFs can be scaled, and (b) animated images don’t have to be GIFs.
It is getting more clear to me, thank you!. I guess, pillow should not handle these jpeg images, which includes a thumbnail, as MPO.
Since there is no such thing as an animated JPEG, I will special-case that.
Environment
Python Version: Python 3.7.3 Nikola Version: Nikola v8.0.3 Operating System: openSuse Tumbleweed / Windows 10
Description:
After i run
nikola build
it creates new thumbnail images, but with the same size like the source images. If you want, you can check it by yourself with the images from my photo blog repository [1].[1] My personal photo blog https://gitlab.com/marcuskammer/photoblog/tree/nikola/photoblog/galleries/travel