image
image copied to clipboard
Fix for orientation issue of JPEG images
I believe I have resolved the orientation issue. For more information on this topic, you can refer to the following article: https://magnushoff.com/articles/jpeg-orientation/
To recreate the issue, simply rotate a JPEG image on macOS, which will add orientation metadata to the EXIF data of the image.
The problem at hand is as follows :
this function will help you to get the orientation of image
pub fn get_jpeg_orientation(file_path: PathBuf) -> Result<u32, ()> {
let file = std::fs::File::open(file_path).expect("problem opening the file");
let mut bufreader = std::io::BufReader::new(&file);
let exifreader = exif::Reader::new();
let exif = exifreader
.read_from_container(&mut bufreader)
.expect("failed to read the exifreader");
let orientation: u32 = match exif.get_field(Tag::Orientation, In::PRIMARY) {
Some(orientation) => match orientation.value.get_uint(0) {
Some(v @ 1..=8) => v,
_ => 1,
},
None => 1,
};
Ok(orientation)
}
and you can use it like this to get the right orientation at the end
if orientation == 2 {
// filp H
img = DynamicImage::ImageRgba8(imageops::flip_horizontal(&img));
} else if orientation == 3 {
// rotate180
img = DynamicImage::ImageRgba8(imageops::rotate180(&img));
} else if orientation == 4 {
// filp H
img = DynamicImage::ImageRgba8(imageops::flip_horizontal(&img));
} else if orientation == 5 {
// rotate 90 & filp H
img = DynamicImage::ImageRgba8(imageops::rotate90(&img));
img = DynamicImage::ImageRgba8(imageops::flip_horizontal(&img));
} else if orientation == 6 {
// rotate90
img = DynamicImage::ImageRgba8(imageops::rotate90(&img));
} else if orientation == 7 {
// filp H & rotate 270
img = DynamicImage::ImageRgba8(imageops::rotate270(&img));
img = DynamicImage::ImageRgba8(imageops::flip_horizontal(&img));
} else if orientation == 8 {
// rotate 270
img = DynamicImage::ImageRgba8(imageops::rotate270(&img));
}
Thank you very much for sharing this code; it works really well.
I found there is a little typo, when orientation == 4
, it should be a vertical flip:
} else if orientation == 4 {
// filp V
img = DynamicImage::ImageRgba8(imageops::flip_vertical(&img));
I have referenced it to create a simplified version and applied it to Yazi (a terminal file manager with built-in image preview):
fn rotate(mut img: DynamicImage, orientation: u8) -> DynamicImage {
let rgba = img.color().has_alpha();
img = match orientation {
2 => DynamicImage::ImageRgba8(imageops::flip_horizontal(&img)),
3 => DynamicImage::ImageRgba8(imageops::rotate180(&img)),
4 => DynamicImage::ImageRgba8(imageops::flip_vertical(&img)),
5 => DynamicImage::ImageRgba8(imageops::flip_horizontal(&imageops::rotate90(&img))),
6 => DynamicImage::ImageRgba8(imageops::rotate90(&img)),
7 => DynamicImage::ImageRgba8(imageops::flip_horizontal(&imageops::rotate270(&img))),
8 => DynamicImage::ImageRgba8(imageops::rotate270(&img)),
_ => img,
};
if !rgba {
img = DynamicImage::ImageRgb8(img.into_rgb8());
}
img
}
Just leaving it here in case someone needs :)
thank you, it works...