Rotating/orienting a JPG with the image library

Why I'm doing this

I wanted to write a simple web app (purely client-side) which would stitch two images together. I tried to do it with <canvas>, but I soon found out that on iOS the <canvas> size can't be bigger than 4096x4096px.

So I thought that this is a perfect use case for some Rust through Wasm.

The problem

After some research, I settled on the image library and I wrote a prototype. It works just fine, maybe it's a bit slow but I can work on that later.

The problem is that the crate is so low-level that I have to take care of rotating the JPGs by myself. I found a good article about JPG orientation, found a simpler implementation in JS based on <cavas>, but I'm struggling to figure out what would be the best way to do it with the image crate.

Some possible solutions

The image::imageops module

There's the image::imageops module with functions like flip_horizontal_in_place or rotate180_in_place. With these two I could accomplish two out of the three operations outlined in that article without allocating creating a whole new ImageBuffer object. Flipping diagonally OTOH would need to be implemented as rotate 90 degrees clockwise then flip horizontally, the former of which creates a new ImageBuffer. Not the optimal solution but so far this is the only way forward that I can see.

The imageproc::geometric_transformations module

The imageproc::geometric_transformations has stuff like Projection and warp. Projection is stored as a matrix which might be useful to do the orientation like in the article, but I really know almost nothing about matrices. On top of that, the warp function says that "The returned image has the same dimensions as image", so I'm not really sure how I could use it for orientation. Maybe that's the warp_into's job?

Use some other crate for orienting the JPGs

I tried looking for other crates, but couldn't find any that would work with Wasm and work on buffers, not files. For me it just seems to be a common enough operation that someone would've taken care of that already, but perhaps I'm wrong. :smirk:

Is there any other solution that I missed? Do I need to implement that by hand or did I miss a crate that can already do that? Is using image::imageops the best thing to do here or can I use this library or imageproc in a way that would make it easier to orient an image than I described?

  • Flipping diagonally is a 180deg rotation.
  • Rotating by 90 or 270deg means changing the data order. This could be implemented in place, but is probably not worth it.

I don't know how to read the image rotation from the exiv metadata.. but there is probably a crate for it.

Hmm, as far as I understand it, it is not? At least that's what the article says:

2021-07-13 at 15.53

Yeah, I just saw that kamadak-exif has a pretty nice API for that and it should work with Wasm.

My bad. I assumed diagonally meant two flips (one vertcal and one horizontal).
I think you can use
but with destination.put_pixel(y, x, p).

(The matrix for it flips x and y values, which is what this function does.)

For now I went with a naive solution until I figure out how to use transformation matrices.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.