Resizing Images in Rust, Now with Exif Orientation Support
Posted4 months agoActive4 months ago
alexwlchan.netTechstory
calmpositive
Debate
40/100
Image ProcessingRustExif Metadata
Key topics
Image Processing
Rust
Exif Metadata
The post discusses a Rust library update that adds EXIF orientation support when resizing images, sparking a discussion on the purpose and handling of EXIF metadata.
Snapshot generated from the HN discussion
Discussion Activity
Active discussionFirst comment
4d
Peak period
14
Day 5
Avg / period
5.3
Comment distribution32 data points
Loading chart...
Based on 32 loaded comments
Key moments
- 01Story posted
Sep 9, 2025 at 6:31 AM EDT
4 months ago
Step 01 - 02First comment
Sep 13, 2025 at 4:29 AM EDT
4d after posting
Step 02 - 03Peak activity
14 comments in Day 5
Hottest window of the conversation
Step 03 - 04Latest activity
Sep 18, 2025 at 12:17 AM EDT
4 months ago
Step 04
Generating AI Summary...
Analyzing up to 500 comments to identify key contributors and discussion patterns
ID: 45180094Type: storyLast synced: 11/20/2025, 1:08:48 PM
Want the full context?
Jump to the original sources
Read the primary article or dive into the live Hacker News thread when you're ready.
I could also imagine that the earliest digital cameras wouldn't have had the processing power, or RAM to store the entire image in memory after reading it from the sensor, in order to do such a rotation. Hence EXIF rotation as a cheap alternative.
https://www.betterjpeg.com/lossless-rotation.htm
They offer three "solutions" to the issue of partial blocks:
- cut them off and stop worrying about it
- show whatever the original JPEG encoder put there and stop worrying about it
- replace whatever the original JPEG encoder put there and stop worrying about it
I cannot imagine anyone honestly considering these and then shipping them. It's fine if the user manually consents, but automated, this is pretty objectionable. Extending the image in arbitrary ways or cutting off of it is really not what I'd expect from a codec to do when I ask it to perform a lossless transformation, particularly specific ones, like flip and rotate, which I'd expect to be outright periodic. And periodicity is violated immediately with the dimensions changing.
Are all JPEGs photos, following sensor pixel dimensions?
> why does EXIF transform metadata exist?
Because there are times when it is useful to be able to quickly and losslessly rotate a photo. For example an image viewer might provide quick options to rotate a photo (in case it did end up rotated the wrong way originally).
Probably this should just have been part of the actual image format rather than metadata, but that isn't how it played out.
> why doesn't the camera itself perform a simple rotation or mirror
There could be various reasons. The simplest is that adjusting the rotation naturally happens later in the pipeline than lossy encoding. You don't want to re-encode for quality and performance reasons so just slap on the metadata. The other could be that it is less expensive to avoid rotating. In many cameras the encoding is handled by specialized hardware, adding a way to rotate the raw pixels is likely more expensive than always having the source pixel map to the same input pixel in the encoder. There is no hard reason it couldn't be done, but in many situations it is cheaper to do it this way.
I can only imagine caring when it comes to streaming a very large image serially, and then I still have no idea what preference I would have (other than that I get the metadata first.)
As an analogy, if I have some irreplaceable video that has a bad aspect ratio, I fix it in the metadata, I don't transcode it. The data is a blob, the metadata is what tells me how to display it (even if it's just the mimetype.)
As far as cost:
Applying the right tag: 0
Anything else: not 0
Why not include a faster CPU or more RAM? In an industry where people pick one product over the other because of a $10 price difference, you’re never going to convince management to approve the better CPU when a tag solves the problem.
These are hardware companies. They look at software as a nuisance. “fix it in software” is for the downstream.
If you want to rotate a jpeg yourself (which is easily done with "magic in.jpg rotate 90 out.jpg" and, of course, other software) but lossless, there's https://jpegclub.org/jpegtran/ which accomplishes it.
When generating rotated thumbnails (without caring for "lossless") the best strategy in my experience is to first rotate the large original image and then generate the thumbnail afterwards, because image resizing will most often hide any rotation artifacts anyways.
Or is there a benefit to generating the thumbnail in the original rotation then preserving the metadata?
Rotation metadata might be helpful in (larger) thumbnails when images are displayed on mobile devices and responsive web pages. Metadata is easy to transfer, at least when scripting with Exiftool or ImageMagick.
For photos all these assumptions are rather theoretical IMO, because modern cameras create images in sizes which almost always have to be reduced in size for viewing, unless one wants to pixel-peep.
For example, if you wanted to blur or grayscale an image, do you really want to rotate it? When you re-save it, you'll have to remove the exif rotation metadata too.
VipsImage *image = vips_image_new_from_file("something.jpg", "autorotate", TRUE, NULL);
and it'll flip it upright for you and remove any EXIF orientation tag. It isn't the default since it has (obviously) a large memory and cpu cost.
For simple resize and crop it's much better to use the exif tag to adjust the resize and crop parameters (the vipsthumbnail command does this).
In my Go project I’m using the Golang library github.com/davidbyttow/govips/v2.
Images are loaded via `vips.NewImageFromFile()`, which internally calls `vips_image_new_from_file()`. However, `NewImageFromFile()` doesn't support any flags or options beyond the image path, so for JPEGs I manually call `AutoRotate()` before resizing, which wraps `vips_autorot()` — and that works well.
Thanks again!
`govips` was a pretty early binding and wasn't really done the libvips way. It doesn't expose all the operations or options, it's mostly done by hand, and there are a number of leaks and misfeatures.
It's been replaced by `vipsgen`:
https://github.com/cshum/vipsgen
Which is an automatically generated 100% binding. It should have the complete API, it should be very stable and leak-free, and it should be simple to maintain.
`autorot` is pretty expensive. You'll see much better performance if you flip x and y in your crop instead.
I wasn’t aware of `vipsgen`, but it looks great — full coverage and auto-generated bindings are exactly what I’ll be missing in `govips` if the project grows (I hope it will). I’ll definitely give it a try and see how it works.
Also, great tip on avoiding `autorot` by flipping crop coordinates — I hadn’t thought of that! Thanks again for your help!