Skip to content

Commit

Permalink
Use exif data if possible to get orientation of image (#1368)
Browse files Browse the repository at this point in the history
  • Loading branch information
qarmin authored Oct 11, 2024
1 parent db164d3 commit 784497d
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/minimial_version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
run: sudo apt update || true; sudo apt install libgtk-4-dev libheif-dev libraw-dev ffmpeg -y

- name: Setup rust version
run: rustup default 1.79.0
run: rustup default 1.80.0

- name: Build
run: |
Expand Down
46 changes: 46 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion czkawka_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "czkawka_cli"
version = "8.0.0"
authors = ["Rafał Mikrut <[email protected]>"]
edition = "2021"
rust-version = "1.79.0"
rust-version = "1.80.0"
description = "CLI frontend of Czkawka"
license = "MIT"
homepage = "https://github.com/qarmin/czkawka"
Expand Down
3 changes: 2 additions & 1 deletion czkawka_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "czkawka_core"
version = "8.0.0"
authors = ["Rafał Mikrut <[email protected]>"]
edition = "2021"
rust-version = "1.79.0"
rust-version = "1.80.0"
description = "Core of Czkawka app"
license = "MIT"
homepage = "https://github.com/qarmin/czkawka"
Expand Down Expand Up @@ -76,6 +76,7 @@ libheif-rs = { version = "=0.18.0", optional = true } # Do not upgrade now, sinc
libheif-sys = { version = "=1.14.2", optional = true } # 1.14.3 brake compilation on Ubuntu 22.04, so pin it to this version
anyhow = { version = "1.0.89" }

nom-exif = "2.1.0"

state = "0.6"
trash = "5.1"
Expand Down
2 changes: 1 addition & 1 deletion czkawka_core/src/common_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::duplicate::HashType;
use crate::similar_images::{convert_algorithm_to_string, convert_filters_to_string};

const CACHE_VERSION: &str = "70";
const CACHE_IMAGE_VERSION: &str = "80";
const CACHE_IMAGE_VERSION: &str = "90";

pub fn get_broken_files_cache_file() -> String {
format!("cache_broken_files_{CACHE_VERSION}.bin")
Expand Down
55 changes: 54 additions & 1 deletion czkawka_core/src/common_image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use libheif_rs::{ColorSpace, HeifContext, RgbChroma};
#[cfg(feature = "libraw")]
use libraw::Processor;
use log::{debug, error, info, warn, LevelFilter, Record};
use nom_exif::{ExifIter, ExifTag, MediaParser, MediaSource};
use rawloader::RawLoader;
use symphonia::core::conv::IntoSample;

Expand Down Expand Up @@ -87,7 +88,19 @@ pub fn get_dynamic_image_from_path(path: &str) -> Result<DynamicImage, String> {

if let Ok(res) = res {
match res {
Ok(t) => Ok(t),
Ok(t) => {
let rotation = get_rotation_from_exif(path).unwrap_or(None);
match rotation {
Some(ExifOrientation::Normal) | None => Ok(t),
Some(ExifOrientation::MirrorHorizontal) => Ok(t.fliph()),
Some(ExifOrientation::Rotate180) => Ok(t.rotate180()),
Some(ExifOrientation::MirrorVertical) => Ok(t.flipv()),
Some(ExifOrientation::MirrorHorizontalAndRotate270CW) => Ok(t.fliph().rotate270()),
Some(ExifOrientation::Rotate90CW) => Ok(t.rotate90()),
Some(ExifOrientation::MirrorHorizontalAndRotate90CW) => Ok(t.fliph().rotate90()),
Some(ExifOrientation::Rotate270CW) => Ok(t.rotate270()),
}
}
Err(e) => Err(format!("Cannot open image file \"{path}\": {e}")),
}
} else {
Expand Down Expand Up @@ -185,3 +198,43 @@ pub fn check_if_can_display_image(path: &str) -> bool {

allowed_extensions.iter().any(|ext| extension_str.ends_with(ext))
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ExifOrientation {
Normal,
MirrorHorizontal,
Rotate180,
MirrorVertical,
MirrorHorizontalAndRotate270CW,
Rotate90CW,
MirrorHorizontalAndRotate90CW,
Rotate270CW,
}

pub fn get_rotation_from_exif(path: &str) -> Result<Option<ExifOrientation>, nom_exif::Error> {
let mut parser = MediaParser::new();
let ms = MediaSource::file_path(path)?;
if !ms.has_exif() {
return Ok(None);
}
let exif_iter: ExifIter = parser.parse(ms)?;
for exif_entry in exif_iter {
if exif_entry.tag() == Some(ExifTag::Orientation) {
if let Some(value) = exif_entry.get_value() {
return match value.to_string().as_str() {
"1" => Ok(Some(ExifOrientation::Normal)),
"2" => Ok(Some(ExifOrientation::MirrorHorizontal)),
"3" => Ok(Some(ExifOrientation::Rotate180)),
"4" => Ok(Some(ExifOrientation::MirrorVertical)),
"5" => Ok(Some(ExifOrientation::MirrorHorizontalAndRotate270CW)),
"6" => Ok(Some(ExifOrientation::Rotate90CW)),
"7" => Ok(Some(ExifOrientation::MirrorHorizontalAndRotate90CW)),
"8" => Ok(Some(ExifOrientation::Rotate270CW)),
_ => Ok(None),
};
}
}
}

Ok(None)
}
2 changes: 1 addition & 1 deletion czkawka_gui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "czkawka_gui"
version = "8.0.0"
authors = ["Rafał Mikrut <[email protected]>"]
edition = "2021"
rust-version = "1.79.0"
rust-version = "1.80.0"
description = "GTK frontend of Czkawka"
license = "MIT"
homepage = "https://github.com/qarmin/czkawka"
Expand Down
2 changes: 1 addition & 1 deletion czkawka_gui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ lot build and runtime dependencies.

| Program | Minimal version |
|:-------:|:---------------:|
| Rust | 1.79.0 |
| Rust | 1.80.0 |
| GTK | 4.6 |

### Linux (Ubuntu, but on other OS should work similar)
Expand Down
2 changes: 1 addition & 1 deletion instructions/Compilation.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ New versions of GTK fixes some bugs, so e.g. middle button selection will work o

| Program | Min | What for |
|---------|--------|--------------------------------------------------------------------------------------|
| Rust | 1.79.0 | The minimum version of rust does not depend on anything, so it can change frequently |
| Rust | 1.80.0 | The minimum version of rust does not depend on anything, so it can change frequently |
| GTK | 4.6 | Only for the `GTK` backend |

#### Debian / Ubuntu
Expand Down
2 changes: 1 addition & 1 deletion krokiet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "krokiet"
version = "8.0.0"
authors = ["Rafał Mikrut <[email protected]>"]
edition = "2021"
rust-version = "1.79.0"
rust-version = "1.80.0"
description = "Slint frontend of Czkawka Core"
license = "GPL-3.0-only"
homepage = "https://github.com/qarmin/czkawka"
Expand Down
2 changes: 1 addition & 1 deletion krokiet/ui/gui_state.slint
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export global GuiState {
in-out property <bool> visible_tool_settings;

in-out property <bool> available_subsettings: active_tab == CurrentTab.SimilarImages || active_tab == CurrentTab.DuplicateFiles || active_tab == CurrentTab.SimilarVideos || active_tab == CurrentTab.SimilarMusic || active_tab == CurrentTab.BigFiles || active_tab == CurrentTab.BrokenFiles;
in-out property <CurrentTab> active_tab: CurrentTab.SimilarImages;
in-out property <CurrentTab> active_tab: CurrentTab.DuplicateFiles;
in-out property <bool> is_tool_tab_active: active_tab != CurrentTab.Settings && active_tab != CurrentTab.About;
in-out property <[SelectModel]> select_results_list: [{data: SelectMode.SelectAll, name: "Select All"}, {data: SelectMode.UnselectAll, name: "Deselect All"}, {data: SelectMode.SelectTheSmallestResolution, name: "Select the smallest resolution"}];

Expand Down

0 comments on commit 784497d

Please sign in to comment.