contao / image

Contao Image Library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Read EXIF metadata and show images with orientation

agoat opened this issue · comments

I think there should be support for image orientation.
Currently pictures taken in portrait format are displayed with the wrong orientation.

I'm not sure where it should be integrated. Either the images should be rotated to the right orientation during the upload process, or the orientation should be taken into account with each resize.

The imagine library support reading Exif metadata (https://imagine.readthedocs.io/en/latest/usage/metadata.html#exif-metadata-reader). They warn that it adds some overhead to the image handling, but I don't think it's too much in relation to the time needed for the resize process itself.
BTW, Nextcloud is supporting image orientation and it's incredible fast on my virtual server, so maybe the overhead is negligible.

I'm not sure where it should be integrated.

I'm not either.

Either the images should be rotated to the right orientation during the upload process

But this would modify the original file and re-encode the JPEG data. Is that always desired?

or the orientation should be taken into account with each resize.

This would make the resized images behave differently in the browser than the original file does. And we would also have to adapt all calls to getimagesize() and rotate the values.

Sadly browsers themselves are inconsistent in handling this topic, see https://caniuse.com/#feat=css-image-orientation

I think the best option would be to make it optional. Either via a Setting like “Auto-rotate images on upload” or by adding a „repair“ button next to EXIF images in the file manager.

Either via a Setting like “Auto-rotate images on upload” or by adding a „repair“ button next to EXIF images in the file manager.

@contao/developers What do you think?

I think auto rotation might confuse users who have no clue about EXIF. A repair button next to the image would allow us to provide additional information. A separate view could even allow for a setting where you could configure whether the original should be replaced or not etc.

+1 for always using the auto-rotate information if it is present. I cannot think of a use case where you would want to use a wrongly rotated image.

I think a repair button would be insufficient. Consider this use case: you provide a front end form with a file upload, where you directly upload an image from your smartphone camera. This uploaded file will then be shown directly in the front end - but it might have the wrong orientation.

In this case an option for the file upload form field to automatically transform the image would be the most practical one I think.

Rotating the image only during image resize would be insufficient, if you show the original image in a lightbox for example (e.g. through Contao's own text, image and gallery content element for example).

In this case an option for the file upload form field to automatically transform the image would be the most practical one I think.

I think a global setting that affects all image uploads should be sufficient, don’t you think?

Fine by me. I personally can't think of a use case where I would want to keep the original image anyway :)

Why not simply add a rotate feature? This would also allow to fix images that do not have EXIF data but are incorrectly rotated.

AFAIR we agreed that we don’t want to create an image editing software inside Contao. If we add a rotate feature we might also add cropping, resizing, contrast and many more.

I think the best solution would be to auto-rotate images on upload (based on the EXIF data) and make it possible to opt out with a global setting.

Only having an option to manually rotate an image wouldn't suffice - if your application accepts user uploaded images, that are then immediately displayed on the website.

I think the best solution would be to auto-rotate images on upload (based on the EXIF data) and make it possible to opt out with a global setting.

Maybe we should add a switch to respect the orientation from the EXIF data either during upload or image resizing (in the frontend).

I never let Contao resize images on upload. Always keep the original and resize for the frontend output.

For example the nextcloud project saves the original images (as the goal is to share files) but shows an preview for jpg files. And that's pretty fast.

So I recommend a global setting to fix(?) orientation during upload (based on EXIF data, but then the EXIF data will be lost or have to be rewritten) or store the (resized) image with orignal orientation (with original EXIF data) and take the orientation into account when resizing in the frontend.

or store the (resized) image with orignal orientation (with original EXIF data) and take the orientation into account when resizing in the frontend.

This would not work well, see #44 (comment) and #44 (comment)

This would not work well, see #44 (comment) and #44 (comment)

If I'm going to show the original (uploaded) image, then I should resize and orientate images during upload (as I would do in my Imageprogram when preparing images for the web). We can't cover every situation.

IMO the orientation information of an image should always be used when resizing - which is the same as building a new image (without EXIF) from the original (with EXIF), but with different dimension. See also #44 (comment).

Maybe it's enough to have it optional to 'auto-rotate' images when resizing (if EXIF orientation info is present). This will happen when images are uploaded and(!) resized or when the images will be resized during frontend output.

If I'm going to show the original (uploaded) image, then I should resize and orientate images during upload (as I would do in my Imageprogram when preparing images for the web). We can't cover every situation.

Uploading an image via the front end form and then displaying all uploaded images in a gallery content element should be a fairly straight forward use case. And for this case the original image must be transformed directly after uploading.

Uploading an image via the front end form and then displaying all uploaded images in a gallery content element should be a fairly straight forward use case

I don't see a problem here.
If 'auto-rotation' is enabled and images will be resized during upload, all fixed.
If 'auto-rotation' is enabled and images will not be resized during upload but(!) a resized preview image will be shown in a gallery content element, fixed too.

If the original image is shown directly then you have to be sure all images (with EXIF orientation) have to be resized.
But a forced orientation transform when uploading images (whether they are resized or not) should be avoided, because there will be ever a loss of quality. For this use case we can add an extra option in the front end upload form/module.

If 'auto-rotation' is enabled and images will not be resized during upload but(!) a resized preview image will be shown in a gallery content element, fixed too.

No, the image will be wrong in the lightbox.

I suggest the following.

  1. Always consider the EXIF orientation during resizing.
  2. Add an option to force re(orientation) on upload.
2\. Add an option to force re(orientation) on upload.

That's what we already suggested ;)

That's what we already suggested ;)

Well, then we're in agreement ;-)
Sometimes I'm somewhat sluggish in my head.

I just wanted to be sure that images could be uploaded without being changed automatically.

just stumbled about this css

#boxContent img {
  image-orientation: from-image;
}

Unfortunately not the greatest support yet https://caniuse.com/#feat=css-image-orientation :(
I'm not the biggest fan of irreversible altering user-uploaded content but an option might be ok.

  1. Always consider the EXIF orientation during resizing.

The longer I’m thinking about it, the more appealing it looks to me. We just have to run the lightbox images through the resizer too, and if it detects an EXIF orientation it should generate a rotated image instead of returning the original.

Should be fairly simple to implement in

image/src/Resizer.php

Lines 139 to 142 in 93d47eb

// Skip resizing if it would have no effect
if (!$image->getDimensions()->isRelative() && $coordinates->isEqualTo($image->getDimensions()->getSize())) {
return $this->createImage($image, $image->getPath());
}

Closed in favor of #52