Live data from Hacker News

Resizing images in Rust, now with EXIF orientation support

alexwlchan.net

21–30 of 35 posts

Re: Resizing images in Rust, now with EXIF orientation support

#22
post #9

You can transfer EXIF information, including the rotation info, with either exiftool or ImageMagick into a thumbnail, to let other software know how to display it correctly. 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 (with…

But it seems that if you are re-encoding the image anyways it is best to just generate it in the "correct" orientation and skip this metadata. Emitting the metadata seems mostly useful if you are trying to avoid re-encoding the image.

Or is there a benefit to generating the thumbnail in the original rotation then preserving the metadata?

Re: Resizing images in Rust, now with EXIF orientation support

#23
post #2

I'm sure there's very good reasoning but I've never been able to convince myself of it - why does EXIF transform metadata exist? If you're taking a selfie, why doesn't the camera itself perform a simple rotation or mirror of the actual image data rather than using EXIF?

There are sort of two questions here:

> 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.

Re: Resizing images in Rust, now with EXIF orientation support

#24
post #9

You can transfer EXIF information, including the rotation info, with either exiftool or ImageMagick into a thumbnail, to let other software know how to display it correctly. 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 (with…

Is jpeg the only format which can be “rotated losslessly” in this way, ie without exif metadata (and excluding any obvious formats like bitmaps or whatever can be trivially rotated) ?

Re: Resizing images in Rust, now with EXIF orientation support

#25
post #11

Wouldn't it make more sense if `image::open()` automatically applied the orientation by default?

Probably for a higher-level crate, (like the one the author wrote), but it adds computational complexity, and you don't want that by default with a low level crate like `image`.

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.

Re: Resizing images in Rust, now with EXIF orientation support

#26
post #9

You can transfer EXIF information, including the rotation info, with either exiftool or ImageMagick into a thumbnail, to let other software know how to display it correctly. 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 (with…

Is jpeg the only format which can be “rotated losslessly” in this way, ie without exif metadata (and excluding any obvious formats like bitmaps or whatever can be trivially rotated) ?

Both PNG and Webp exist in lossless formats which can be easily rotated without loss of quality. Jpeg is different, because its internal structure consists of 8x8 blocks (which, BTW, can be rotated lossless if both sides of the image are multiples of 8, iirc.

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.

Re: Resizing images in Rust, now with EXIF orientation support

#27
post #9

You can transfer EXIF information, including the rotation info, with either exiftool or ImageMagick into a thumbnail, to let other software know how to display it correctly. 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 (with…

But it seems that if you are re-encoding the image anyways it is best to just generate it in the "correct" orientation and skip this metadata. Emitting the metadata seems mostly useful if you are trying to avoid re-encoding the image. Or is there a benefit to generating the thumbnail in the original rotation then preserving the metadata?

Sure, generating the "correct" format would be a good decision. When you change pixel orientation, you'll need to either update or clear the EXIF orientation info to reflect the new pixel data.

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.

Re: Resizing images in Rust, now with EXIF orientation support

#28
post #9

You can transfer EXIF information, including the rotation info, with either exiftool or ImageMagick into a thumbnail, to let other software know how to display it correctly. 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 (with…

Is jpeg the only format which can be “rotated losslessly” in this way, ie without exif metadata (and excluding any obvious formats like bitmaps or whatever can be trivially rotated) ?

From what I know it can't be "rotated losslessly" in all cases, only if the dimensions of the images are multiples of the MCU which are block of pixels whose size is determined by the chroma subsampling. Ex.: With the common "4:2:0" subsampling the MCU is 16x16 the image's height and width must be exactly multiples of 16, otherwise I think it's just visually lossless and uses some tricks that I'm still not sure how they work.

Re: Resizing images in Rust, now with EXIF orientation support

#29
post #5

Earlier quoted context omitted.

Pretty sure you can rotate JPEG images lossless. But it’s still simpler to just modify metadata.

A quick search suggests to me that it's only a lossless process if the image dimensions are a clean integer multiple of 8 or 16 (as the blocks can be 8x8, 8x16, 16x8, or 16x16), otherwise the edges must be reencoded. Never written a JPEG codec though, so happy to be proven wrong.

This is true, and others have mentioned it, but I think people are underestimating just how universal sensor dimensions being a multiple of 16 is — I really can’t think of any exceptions.

Re: Resizing images in Rust, now with EXIF orientation support

#30
I ran into the same issue when working with image processing in Go using libvips. By default, libvips ignores EXIF orientation too, so I had to explicitly read and apply the orientation tag before doing any resize or crop. Otherwise users ended up with upside-down processed images from photos. Glad to see this is getting better in Rust.
Post reply on HN