Fixed XF.AttachmentManager/XF.ImageTools destroys EXIF data

DragonByte Tech

Well-known member
Affected version
2.3.6
Currently, it is impossible to fully preserve an attachment's EXIF data. There's a number of factors at play here:

  • The bundled ExifReader library fails to obtain all EXIF data from sample photos found here: https://www.geoimgr.com/sample-photos.html and other sample photos I have tested with
  • XF.ImageTools.resize() does not abort resizing if the global image size limits are set to 0 or left blank
  • XF.ImageTools.resize() will always discard the old image because the canvas size will always be smaller than the original image

I have attached a sample image which, when adding debug statements, causes these prints:
1746285809825.webp

This is the relevant portion of XF.ImageTools.resize():
JavaScript:
                            const newFile = new File([blob], file.name, {
                                type: asType,
                                lastModified: file.lastModified,
                            })
                            console.log("New file size:", newFile.size)
                            console.log("Old file size:", file.size)
                            if (!neededResizing && newFile.size >= file.size)
                            {
                                console.log("Preserved old file")
                                resolve(file)
                                return
                            }

                            console.log("Replaced with new file")
                            resolve(newFile)

As seen in this suggestion: https://xenforo.com/community/threads/retain-exif-data-on-optimized-processed-images.225525/ there are numerous instances where preserving all EXIF data is beneficial. Therefore, I suggest the following fix:

Diff:
Index: js/xf/attachment_manager.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/xf/attachment_manager.js b/js/xf/attachment_manager.js
--- a/js/xf/attachment_manager.js
+++ b/js/xf/attachment_manager.js
@@ -1073,6 +1073,12 @@
                         neededResizing = false
                     }
 
+                    if (!neededResizing)
+                    {
+                        resolve(file)
+                        return
+                    }
+
                     if (maxWidth && width > maxWidth)
                     {
                         height *= maxWidth / width
 

Attachments

The bundled ExifReader library fails to obtain all EXIF data from sample photos found here: https://www.geoimgr.com/sample-photos.html and other sample photos I have tested with
This is intentional / working as designed.
If you need full EXIF data you either have to use a custom build of ExifReader or disable client side image processing.


Diff:
Index: js/xf/attachment_manager.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/xf/attachment_manager.js b/js/xf/attachment_manager.js
--- a/js/xf/attachment_manager.js
+++ b/js/xf/attachment_manager.js
@@ -1073,6 +1073,12 @@
                         neededResizing = false
                     }
 
+                    if (!neededResizing)
+                    {
+                        resolve(file)
+                        return
+                    }
+
                     if (maxWidth && width > maxWidth)
                     {
                         height *= maxWidth / width
This kinda defeats the purpose of client side image processing:
Even if no resizing is required converting to WebP (if enabled) usually still decreases upload size (and server processing).
 
Last edited:
It's true that this is deliberate on the whole, and that we don't abort when the resulting file size is smaller (though I would note it's not actually always smaller) since smaller files mean less data and faster uploads. We also only capture basic EXIF data out of the box to save on JS size, and geolocation is a deliberate omission.

However I'm currently looking at making this easier to change for add-ons. We'll maybe ship a full version of ExifReader and allow add-ons to swap it in. Unfortunately even if you do that manually right now, some other adjustments are needed to map the data back to the shape PHP captures natively so trying to sort that first.
 
Thank you for reporting this issue, it has now been resolved. We are aiming to include any changes that have been made in a future XF release (2.3.7).

Change log:
Improve supported EXIF data when client-side image resizing is enabled
There may be a delay before changes are rolled out to the XenForo Community.
 
OK, we can ship a full JPEG/EXIF JS bundle for only ~5kb additional gzipped, so we've gone ahead with that for the next release. The EXIF data should now be retained to the greatest extent possible without requiring changes to third-party code. I've attached a diff.
 

Attachments

OK, we can ship a full JPEG/EXIF JS bundle for only ~5kb additional gzipped, so we've gone ahead with that for the next release. The EXIF data should now be retained to the greatest extent possible without requiring changes to third-party code. I've attached a diff.

Is this new exif.diff enabled here in the support forum? I would like to test how the Exif data are displayed before buying/upgrading to 2.3.
 
I don't think so. FWIW the only EXIF data we store in the core was already maintained in previous versions, so there won't be any noticeable difference here. This is about the ability to capture the data on the server, the data itself is still stripped from the actual images.
 
Any hope to change that in the future? It should be an option in the ACP.
This is not realistically possible:
GD automatically strips EXIF when processing an image, there is no way to avoid this and GD has no functions to add EXIF either.

If you reallly need EXIF within images:
Don't enable WebP, don't set maximum width / height and don't upload images that are rotated.
This way images won't be processed and will thus retain the original EXIF data.

 
There are addons available, which allow the display of specific (not all) Exif data again - even with maximum width / height.

Therefore it is technically possible. It would be great if this would be an option in the ACP in the core, not as an addon. Data like, Camera brand, Camera model, Lens brand & model, focal length (if it is a zoom), ISO, aperture, shutterspeed, metering, over/underexposure etc.

This would help the Media Gallery too, to be more attractive.
 
There are addons available, which allow the display of specific (not all) Exif data again - even with maximum width / height.
Might well be the case, but most certainly not EXIF data that is included within an image that was processed with GD.

Therefore it is technically possible.
Believe whatever you want :)
It is technically impossible to retain EXIF when processing images with GD.
 
How can I check in my xenforo installation, which one is used to change the images?

I found it.

Admin control panel -> Setup -> Options -> Attachments

Has been years when I enabled Imagemagick on all of my forums. Gave better image quality than GD. And Exif data show up with size limitations for width/height etc.

For these settings with IM, it would be great if XF core would allow the Exif data displayed without an additional addon.
 


Write your reply...
Back
Top Bottom