Strip exif information from loaded image in Resizer#loadFile
authorTim Düsterhus <duesterhus@woltlab.com>
Thu, 2 Jul 2020 08:11:59 +0000 (10:11 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Thu, 2 Jul 2020 09:35:57 +0000 (11:35 +0200)
commit89131dd1651f6636884547eec4f9e2470dfae719
tree9221d6a54dc4c075671b652c3741350d4df10ba5
parent768f9331ee70987a035cfe8e932d204706a16202
Strip exif information from loaded image in Resizer#loadFile

Modern browsers take the Exif orientation into account when showing a JPEG
within an HTMLImageElement. Unfortunately this orientation is not only
visual, but extends to the blob received when reading this image into a
canvas.

The JavaScript based image resizer using within the attachment system takes
care reinsert the original Exif data after fetching the resized blob from
pica.js.

This causes the image to be reoriented multiple times, ultimately leading
to an incorrectly oriented image:

1. The browser rotates the image.
2. The server rotates the image again, because the original Exif information
   has been preserved.

To fix this issue we strip the Exif information before handing the blob over
to the HTMLImageElement, forcing the browser to use the raw pixels instead
of pretending to be smart. When the Exif information is reinserted after
resizing the image that will be uploaded will then be reoriented only once:
On the server.

During fixing of this bug it was also investigated whether one can find out
whether the browser reoriented the image, it looks like one cannot. It was
also tested whether setting `image-orientation: none` will have any effect.

It only has in Firefox: When image-orientation: none is set you will get
the behavior as if no Exif information is present.
In Chrome the source image will not be be reoriented when rendered inside
of the DOM. Reading the pixel values however still returns the reoriented
garbage.

Thus stripping the exif information is the best solution to combat web
browsers attempting to be smart. Unfortunately it comes with an increased
processing requirement, because the raw blob (possible multiple megabytes)
will need to be processed to strip the Exif data.
wcfsetup/install/files/js/WoltLabSuite/Core/Image/Resizer.js