Alexander Halser 28 Posted Sunday at 11:26 PM This is a blank FMX form in Delphi 11 with a TImage control, that loads a JPEG. The JPEG picture was created with a Samsung smart phone in portrait mode. Hence, the picture has a width of 2268 and a height of 4032 pixels. The JPEG's EXIF header states that orientation is portrait. That's obvious for everyone who looks at the picture, except for Delphi Firemonkey. TBitmap.LoadfromFile() ignores the EXIF orientation altogether and loads the JPEG with its physical dimensions (which are width 4032 and height 2268 pixels). It doesn't rotate the picture after loading. Has anyone solved this nasty problem for FMX? Share this post Link to post
Alexander Halser 28 Posted 8 hours ago I wonder if anyone is interested in a solution... 😉 Just in case you are, here is what I did. Neither FMX nor VCL will honor the orientation information in the EXIF header inside the JPEG. For FMX: neither on Windows nor on macOS. And probably not on iOS, either. For Android and Linus, you need to test for yourself, maybe they do. The only solution is to read the EXIF header, extract the Orientation tag and apply the necessary transformations to the image after loading. There are several components for Delphi to read EXIF headers, some do work, some don't. The best known unit is CCR-Exif (https://github.com/Wolfcast/ccr-exif), which does everything and works quite well. It can read and write EXIF tags. I've created my own, because CCR-Exif seems like overkill (after all, I just want to know 1 single byte in the JPEG) If you want to display JPEG images correctly in your FMX application, I have published my little unit on SourceForge, It's as small and fast as possible with really minimal overhead. The first function JPEGRotationFromStream() will work for VCL as well! So you can adapt it and use it for your VCL app, too. But FMX has this nice little class called TBitmapSurface, which easily does the Rotate, Mirror and Flip transformations that are required to display the JPEG correctly. So, for FMX this unit goes the full length and delivers a TBitmap that's just right. The unit might be useful for VCL as well, but you have to go an extra mile to apply the transformations. SourceForge Download: https://sourceforge.net/projects/delphi-fmx-jpeg-loader-exif/ 2 Share this post Link to post
Anders Melander 1860 Posted 6 hours ago 22 hours ago, Alexander Halser said: That's obvious for everyone who looks at the picture, except for Delphi Firemonkey. TBitmap.LoadfromFile() ignores the EXIF orientation altogether and loads the JPEG with its physical dimensions (which are width 4032 and height 2268 pixels). It doesn't rotate the picture after loading. FWIW, TBitmap/TJPEGImage are low-level image containers. It's not their job to rotate or mirror the image because they don't know what you want to do with the image after load. So, if anything, the problem is that the classes don't surface the EXIF information so you can apply the transformation after load if you want to. 1 Share this post Link to post
Alexander Halser 28 Posted 6 hours ago Just now, Anders Melander said: problem is that the classes don't surface the EXIF information Agreed. But this EXIF information is crucial (at least the orientation), from a practical point of view. Share this post Link to post
Anders Melander 1860 Posted 6 hours ago Definitely. I'm not denying that it's a problem. I'm just saying that the problem isn't that it doesn't rotate automatically (because that would also be a problem). The problem is that it doesn't give us any way of knowing that the image needs to be rotated be display. You should probably report it as a bug against FMX. 1 Share this post Link to post
Alexander Halser 28 Posted 6 hours ago 3 minutes ago, Anders Melander said: The problem is that it doesn't give us any way of knowing that the image needs to be rotated be display. Yes, that's the core issue. When loading an image, we must know - or be able to know - if it requires extra handling. Then we can make an informed decision. For myself, the issue is solved with the Jpeg-load-helper unit. Now I have to implement that in VCL as well... 🙂 Share this post Link to post