Heic or heif support, don't know (#750)
This commit is contained in:
parent
56fc29fa4f
commit
db09dc9363
34
.github/workflows/linux.yml
vendored
34
.github/workflows/linux.yml
vendored
|
@ -32,17 +32,10 @@ jobs:
|
|||
linux-cli-${{github.ref}}-${{github.sha}}
|
||||
|
||||
- name: Install basic libraries
|
||||
run: sudo apt-get update; sudo apt install libgtk-4-dev libasound2-dev -y
|
||||
|
||||
- name: Build CLI Debug
|
||||
run: cargo build --bin czkawka_cli
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUSTFLAGS: "-C debuginfo=0"
|
||||
if: ${{ matrix.type == 'debug'}}
|
||||
run: sudo apt-get update; sudo apt install libgtk-4-dev libheif-dev -y
|
||||
|
||||
- name: Build CLI Release
|
||||
run: cargo build --release --bin czkawka_cli
|
||||
run: cargo build --release --bin czkawka_cli --features heif
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUSTFLAGS: "-C debuginfo=0"
|
||||
|
@ -150,21 +143,26 @@ jobs:
|
|||
linux-gui-${{github.ref}}-${{github.sha}}
|
||||
|
||||
- name: Install Gtk, Mingw, unzip, zip and wget
|
||||
run: sudo apt-get update; sudo apt install libgtk-4-dev libasound2-dev fuse libfuse2 -y
|
||||
run: sudo apt-get update; sudo apt install libgtk-4-dev fuse libfuse2
|
||||
if: ${{ matrix.toolchain == '1.60.0' }}
|
||||
|
||||
- name: Build GUI Debug
|
||||
run: cargo build --bin czkawka_gui
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUSTFLAGS: "-C debuginfo=0"
|
||||
if: ${{ matrix.type == 'debug'}}
|
||||
- name: Install Gtk, Mingw, unzip, zip and wget and libheif
|
||||
run: sudo apt-get update; sudo apt install libgtk-4-dev fuse libfuse2 libheif-dev -y
|
||||
if: ${{ matrix.toolchain == 'stable' }}
|
||||
|
||||
- name: Build GUI Release
|
||||
run: cargo build --release --bin czkawka_gui
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUSTFLAGS: "-C debuginfo=0"
|
||||
if: ${{ matrix.type == 'release'}}
|
||||
if: ${{ (matrix.type == 'release') && (matrix.toolchain == '1.60.0') }}
|
||||
|
||||
- name: Build GUI Release
|
||||
run: cargo build --release --bin czkawka_gui --features heif
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUSTFLAGS: "-C debuginfo=0"
|
||||
if: ${{ (matrix.type == 'release') && (matrix.toolchain == 'stable') }}
|
||||
|
||||
- name: Store Linux GUI
|
||||
uses: actions/upload-artifact@v2
|
||||
|
@ -214,7 +212,7 @@ jobs:
|
|||
linux-appimage-gui-${{github.ref}}-${{github.sha}}
|
||||
|
||||
- name: Install Gtk,
|
||||
run: sudo apt-get update; sudo apt install libgtk-4-dev libasound2-dev librsvg2-dev wget fuse libfuse2 -y
|
||||
run: sudo apt-get update; sudo apt install libgtk-4-dev libheif-dev librsvg2-dev wget fuse libfuse2 -y
|
||||
|
||||
- name: Build GUI Release
|
||||
run: cargo build --release --bin czkawka_gui
|
||||
|
|
20
.github/workflows/mac.yml
vendored
20
.github/workflows/mac.yml
vendored
|
@ -31,15 +31,8 @@ jobs:
|
|||
restore-keys: |
|
||||
mac-cli-${{github.ref}}-${{github.sha}}
|
||||
|
||||
- name: Build CLI Debug
|
||||
run: cargo build --bin czkawka_cli
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUSTFLAGS: "-C debuginfo=0 -D warnings"
|
||||
if: ${{ matrix.type == 'debug'}}
|
||||
|
||||
- name: Build CLI Release
|
||||
run: cargo build --release --bin czkawka_cli
|
||||
run: cargo build --release --bin czkawka_cli --features heif
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUSTFLAGS: "-C debuginfo=0 -D warnings"
|
||||
|
@ -73,17 +66,10 @@ jobs:
|
|||
run: rm '/usr/local/bin/2to3'
|
||||
|
||||
- name: Install GTK4
|
||||
run: brew install rust gtk4
|
||||
|
||||
- name: Build GUI Debug
|
||||
run: cargo build --bin czkawka_gui
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUSTFLAGS: "-C debuginfo=0 -D warnings"
|
||||
if: ${{ matrix.type == 'debug'}}
|
||||
run: brew install rust gtk4 libheif
|
||||
|
||||
- name: Build GUI Release
|
||||
run: cargo build --release --bin czkawka_gui
|
||||
run: cargo build --release --bin czkawka_gui --features heif
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
RUSTFLAGS: "-C debuginfo=0 -D warnings"
|
||||
|
|
4
.github/workflows/quality.yml
vendored
4
.github/workflows/quality.yml
vendored
|
@ -28,8 +28,8 @@ jobs:
|
|||
components: rustfmt, clippy
|
||||
override: true
|
||||
|
||||
- name: Install Gtk
|
||||
run: sudo apt-get update; sudo apt install -y libgtk-4-dev libasound2-dev
|
||||
- name: Install Gtk 4
|
||||
run: sudo apt-get update; sudo apt install -y libgtk-4-dev libheif-dev -y
|
||||
|
||||
- name: Check the format
|
||||
run: cargo fmt --all -- --check
|
||||
|
|
79
Cargo.lock
generated
79
Cargo.lock
generated
|
@ -224,9 +224,9 @@ checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
|
|||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.9.1"
|
||||
version = "3.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
|
||||
checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
|
@ -461,6 +461,7 @@ dependencies = [
|
|||
name = "czkawka_core"
|
||||
version = "4.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"audio_checker",
|
||||
"bincode",
|
||||
"bitflags",
|
||||
|
@ -479,6 +480,7 @@ dependencies = [
|
|||
"image_hasher",
|
||||
"imagepipe",
|
||||
"infer",
|
||||
"libheif-rs",
|
||||
"lofty",
|
||||
"mime_guess",
|
||||
"once_cell",
|
||||
|
@ -718,7 +720,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide 0.5.1",
|
||||
"miniz_oxide 0.5.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -917,9 +919,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gdk4"
|
||||
version = "0.4.7"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4a2fc0bd03d59383fc10b71a8cb731a1fac2998732a36a0c03e9b1de1513218"
|
||||
checksum = "4fabb7cf843c26b085a5d68abb95d0c0bf27a9ae2eeff9c4adb503a1eb580876"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cairo-rs",
|
||||
|
@ -933,9 +935,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gdk4-sys"
|
||||
version = "0.4.7"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b34a7e60e0c0103cffeaf7baf9dc05358dca74fd350a0c4d61c6c3083ca9fdf1"
|
||||
checksum = "efe7dcb44f5c00aeabff3f69abfc5673de46559070f89bd3fbb7b66485d9cef2"
|
||||
dependencies = [
|
||||
"cairo-sys-rs",
|
||||
"gdk-pixbuf-sys",
|
||||
|
@ -1098,9 +1100,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gsk4"
|
||||
version = "0.4.7"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14d5a47a78c682bb67496b562495ed84972c0512ba0654888c4dc92b80a85bd3"
|
||||
checksum = "05e9020d333280b3aa38d496495bfa9b50712eebf1ad63f0ec5bcddb5eb61be4"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cairo-rs",
|
||||
|
@ -1114,9 +1116,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gsk4-sys"
|
||||
version = "0.4.2"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e31d21d7ce02ba261bb24c50c4ab238a10b41a2c97c32afffae29471b7cca69b"
|
||||
checksum = "7add39ccf60078508c838643a2dcc91f045c46ed63b5ea6ab701b2e25bda3fea"
|
||||
dependencies = [
|
||||
"cairo-sys-rs",
|
||||
"gdk4-sys",
|
||||
|
@ -1130,9 +1132,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gtk4"
|
||||
version = "0.4.7"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb5d40303dabe4608fc260de2bd7563da6f85bc90af956323f0cd8ae0abcfe03"
|
||||
checksum = "c64f0c2a3d80e899dc3febddad5bac193ffcf74a0fd7e31037f30dd34d6f7396"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cairo-rs",
|
||||
|
@ -1153,9 +1155,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gtk4-macros"
|
||||
version = "0.4.7"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f3c4aa605fb3d78205c7aef0eeaa6db61d8cc4dd05a465dc6ffdfdaee84f825"
|
||||
checksum = "fafbcc920af4eb677d7d164853e7040b9de5a22379c596f570190c675d45f7a7"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"proc-macro-crate",
|
||||
|
@ -1168,9 +1170,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gtk4-sys"
|
||||
version = "0.4.5"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c47c075e8f795c38f6e9a47b51a73eab77b325f83c0154979ed4d4245c36490d"
|
||||
checksum = "5bc8006eea634b7c72da3ff79e24606e45f21b3b832a3c5a1f543f5f97eb0f63"
|
||||
dependencies = [
|
||||
"cairo-sys-rs",
|
||||
"gdk-pixbuf-sys",
|
||||
|
@ -1517,6 +1519,25 @@ version = "0.2.126"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||
|
||||
[[package]]
|
||||
name = "libheif-rs"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a28e98f7e0b934f2d240bbd438b02d82d2bbce34a97d5cf25767e2c2ff249f7"
|
||||
dependencies = [
|
||||
"enumn",
|
||||
"libheif-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libheif-sys"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9426b3c799fe53b9636aac80ddc60efa5060c1959faee2e9d3edf0da6b8536a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.4"
|
||||
|
@ -1643,9 +1664,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.5.1"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082"
|
||||
checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
@ -1800,12 +1821,12 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
|||
|
||||
[[package]]
|
||||
name = "open"
|
||||
version = "2.1.2"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0524af9508f9b5c4eb41dce095860456727748f63b478d625f119a70e0d764a"
|
||||
checksum = "f2423ffbf445b82e58c3b1543655968923dd06f85432f10be2bb4f1b7122f98c"
|
||||
dependencies = [
|
||||
"pathdiff",
|
||||
"winapi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1841,9 +1862,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
|
@ -2010,7 +2031,7 @@ dependencies = [
|
|||
"bitflags",
|
||||
"crc32fast",
|
||||
"deflate 1.0.0",
|
||||
"miniz_oxide 0.5.1",
|
||||
"miniz_oxide 0.5.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2716,9 +2737,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.95"
|
||||
version = "1.0.96"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942"
|
||||
checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2999,9 +3020,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93bbc61e655a4833cf400d0d15bf3649313422fa7572886ad6dab16d79886365"
|
||||
checksum = "c6d5d669b51467dcf7b2f1a796ce0f955f05f01cafda6c19d6e95f730df29238"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
|
|
|
@ -9,8 +9,16 @@ homepage = "https://github.com/qarmin/czkawka"
|
|||
repository = "https://github.com/qarmin/czkawka"
|
||||
|
||||
[dependencies]
|
||||
czkawka_core = { path = "../czkawka_core", version = "4.1.0" }
|
||||
structopt = "0.3.26"
|
||||
|
||||
# For enum types
|
||||
image_hasher = "1.0.0"
|
||||
|
||||
[dependencies.czkawka_core]
|
||||
path = "../czkawka_core"
|
||||
version = "4.1.0"
|
||||
features = []
|
||||
|
||||
[features]
|
||||
default = []
|
||||
heif = ["czkawka_core/heif"]
|
|
@ -64,3 +64,10 @@ imagepipe = "0.5.0"
|
|||
# Checking for invalid extensions
|
||||
mime_guess = "2.0.4"
|
||||
infer = "0.8.0"
|
||||
|
||||
libheif-rs = { version = "0.15.0", optional = true }
|
||||
anyhow = { version = "1.0.57", optional = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
heif = ["dep:libheif-rs", "dep:anyhow"]
|
|
@ -9,20 +9,26 @@ use directories_next::ProjectDirs;
|
|||
use image::{DynamicImage, ImageBuffer, Rgb};
|
||||
use imagepipe::{ImageSource, Pipeline};
|
||||
|
||||
#[cfg(feature = "heif")]
|
||||
use anyhow::Result;
|
||||
#[cfg(feature = "heif")]
|
||||
use libheif_rs::{Channel, ColorSpace, HeifContext, RgbChroma};
|
||||
|
||||
/// Class for common functions used across other class/functions
|
||||
pub const RAW_IMAGE_EXTENSIONS: &[&str] = &[
|
||||
".mrw", ".arw", ".srf", ".sr2", ".mef", ".orf", ".srw", ".erf", ".kdc", ".kdc", ".dcs", ".rw2", ".raf", ".dcr", ".dng", ".pef", ".crw", ".iiq", ".3fr", ".nrw", ".nef", ".mos",
|
||||
".cr2", ".ari",
|
||||
];
|
||||
pub const IMAGE_RS_EXTENSIONS: &[&str] = &[
|
||||
".jpg", ".jpeg", ".png", ".bmp", ".tiff", ".tif", ".tga", ".ff", ".jif", ".jfi", ".webp", ".gif", ".ico", ".exr", ".hdr",
|
||||
".jpg", ".jpeg", ".png", ".bmp", ".tiff", ".tif", ".tga", ".ff", ".jif", ".jfi", ".webp", ".gif", ".ico", ".exr",
|
||||
];
|
||||
|
||||
pub const IMAGE_RS_SIMILAR_IMAGES_EXTENSIONS: &[&str] = &[".jpg", ".jpeg", ".png", ".tiff", ".tif", ".tga", ".ff", ".jif", ".jfi", ".bmp", ".webp", ".exr", ".hdr"];
|
||||
pub const IMAGE_RS_SIMILAR_IMAGES_EXTENSIONS: &[&str] = &[".jpg", ".jpeg", ".png", ".tiff", ".tif", ".tga", ".ff", ".jif", ".jfi", ".bmp", ".webp", ".exr"];
|
||||
|
||||
pub const IMAGE_RS_BROKEN_FILES_EXTENSIONS: &[&str] = &[
|
||||
".jpg", ".jpeg", ".png", ".tiff", ".tif", ".tga", ".ff", ".jif", ".jfi", ".gif", ".bmp", ".ico", ".jfif", ".jpe", ".pnz", ".dib", ".webp", ".exr", ".hdr",
|
||||
".jpg", ".jpeg", ".png", ".tiff", ".tif", ".tga", ".ff", ".jif", ".jfi", ".gif", ".bmp", ".ico", ".jfif", ".jpe", ".pnz", ".dib", ".webp", ".exr",
|
||||
];
|
||||
pub const HEIC_EXTENSIONS: &[&str] = &[".heif", ".heifs", ".heic", ".heics", ".avci", ".avcs", ".avif", ".avifs"];
|
||||
|
||||
pub const ZIP_FILES_EXTENSIONS: &[&str] = &[".zip"];
|
||||
|
||||
|
@ -96,6 +102,20 @@ pub fn open_cache_folder(cache_file_name: &str, save_to_cache: bool, use_json: b
|
|||
None
|
||||
}
|
||||
|
||||
#[cfg(feature = "heif")]
|
||||
pub fn get_dynamic_image_from_heic(path: &str) -> Result<DynamicImage> {
|
||||
let im = HeifContext::read_from_file(path)?;
|
||||
let handle = im.primary_image_handle()?;
|
||||
let image = handle.decode(ColorSpace::Rgb(RgbChroma::Rgb), false)?;
|
||||
let width = image.width(Channel::Interleaved).map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
let height = image.height(Channel::Interleaved).map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
let planes = image.planes();
|
||||
let interleaved_plane = planes.interleaved.unwrap();
|
||||
ImageBuffer::from_raw(width, height, interleaved_plane.data.to_owned())
|
||||
.map(DynamicImage::ImageRgb8)
|
||||
.ok_or_else(|| anyhow::anyhow!("Failed to create image buffer"))
|
||||
}
|
||||
|
||||
pub fn get_dynamic_image_from_raw_image(path: impl AsRef<Path> + std::fmt::Debug) -> Option<DynamicImage> {
|
||||
let file_handler = match OpenOptions::new().read(true).open(&path) {
|
||||
Ok(t) => t,
|
||||
|
|
|
@ -18,7 +18,10 @@ use image_hasher::{FilterType, HashAlg, HasherConfig};
|
|||
use rayon::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::common::{get_dynamic_image_from_raw_image, open_cache_folder, Common, IMAGE_RS_SIMILAR_IMAGES_EXTENSIONS, LOOP_DURATION, RAW_IMAGE_EXTENSIONS};
|
||||
#[cfg(feature = "heif")]
|
||||
use crate::common::get_dynamic_image_from_heic;
|
||||
use crate::common::{get_dynamic_image_from_raw_image, open_cache_folder, Common, HEIC_EXTENSIONS, IMAGE_RS_SIMILAR_IMAGES_EXTENSIONS, LOOP_DURATION, RAW_IMAGE_EXTENSIONS};
|
||||
|
||||
use crate::common_directory::Directories;
|
||||
use crate::common_extensions::Extensions;
|
||||
use crate::common_items::ExcludedItems;
|
||||
|
@ -279,9 +282,11 @@ impl SimilarImages {
|
|||
if !self.allowed_extensions.using_custom_extensions() {
|
||||
self.allowed_extensions.extend_allowed_extensions(IMAGE_RS_SIMILAR_IMAGES_EXTENSIONS);
|
||||
self.allowed_extensions.extend_allowed_extensions(RAW_IMAGE_EXTENSIONS);
|
||||
#[cfg(feature = "heif")]
|
||||
self.allowed_extensions.extend_allowed_extensions(HEIC_EXTENSIONS);
|
||||
} else {
|
||||
self.allowed_extensions
|
||||
.validate_allowed_extensions(&[IMAGE_RS_SIMILAR_IMAGES_EXTENSIONS, RAW_IMAGE_EXTENSIONS].concat());
|
||||
.validate_allowed_extensions(&[IMAGE_RS_SIMILAR_IMAGES_EXTENSIONS, RAW_IMAGE_EXTENSIONS, HEIC_EXTENSIONS].concat());
|
||||
if !self.allowed_extensions.using_custom_extensions() {
|
||||
return true;
|
||||
}
|
||||
|
@ -562,13 +567,29 @@ impl SimilarImages {
|
|||
|
||||
let image;
|
||||
|
||||
if !IMAGE_RS_SIMILAR_IMAGES_EXTENSIONS.iter().any(|e| file_name_lowercase.ends_with(e)) {
|
||||
#[allow(clippy::never_loop)] // Required to implement nice if/else
|
||||
'krztyna: loop {
|
||||
if RAW_IMAGE_EXTENSIONS.iter().any(|e| file_name_lowercase.ends_with(e)) {
|
||||
image = match get_dynamic_image_from_raw_image(&file_entry.path) {
|
||||
Some(t) => t,
|
||||
None =>
|
||||
return Some(Some((file_entry, Vec::new())))
|
||||
};
|
||||
} else {
|
||||
break 'krztyna;
|
||||
}
|
||||
|
||||
# [cfg(feature = "heif")]
|
||||
if HEIC_EXTENSIONS.iter().any(|e| file_name_lowercase.ends_with(e)) {
|
||||
image = match get_dynamic_image_from_heic(&file_entry.path.to_string_lossy().to_string()) {
|
||||
Ok(t) => t,
|
||||
Err(_) => {
|
||||
return Some(Some((file_entry, Vec::new())));
|
||||
}
|
||||
};
|
||||
break 'krztyna;
|
||||
}
|
||||
|
||||
// Normal image extension, when any other fail, not using if/else
|
||||
let result = panic::catch_unwind(|| {
|
||||
match image::open(file_entry.path.clone()) {
|
||||
Ok(t) => Ok(t),
|
||||
|
@ -590,8 +611,9 @@ impl SimilarImages {
|
|||
println!("Image-rs library crashed when opening \"{:?}\" image, please check if problem happens with latest image-rs version(this can be checked via https://github.com/qarmin/ImageOpening tool) and if it is not reported, please report bug here - https://github.com/image-rs/image/issues", file_entry.path);
|
||||
return Some(Some((file_entry, Vec::new())));
|
||||
}
|
||||
}
|
||||
|
||||
break 'krztyna;
|
||||
}
|
||||
|
||||
let dimensions = image.dimensions();
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ homepage = "https://github.com/qarmin/czkawka"
|
|||
repository = "https://github.com/qarmin/czkawka"
|
||||
|
||||
[dependencies]
|
||||
czkawka_core = { path = "../czkawka_core", version = "4.1.0"}
|
||||
gdk4 = "0.4.7"
|
||||
glib = "0.15.11"
|
||||
|
||||
|
@ -57,3 +56,11 @@ version = "0.4.7"
|
|||
default-features = false # just in case
|
||||
features = ["v4_6"]
|
||||
|
||||
[dependencies.czkawka_core]
|
||||
path = "../czkawka_core"
|
||||
version = "4.1.0"
|
||||
features = []
|
||||
|
||||
[features]
|
||||
default = []
|
||||
heif = ["czkawka_core/heif"]
|
|
@ -1,17 +1,24 @@
|
|||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[cfg(feature = "heif")]
|
||||
use czkawka_core::common::get_dynamic_image_from_heic;
|
||||
use czkawka_core::common::HEIC_EXTENSIONS;
|
||||
use gdk4::gdk_pixbuf::{InterpType, Pixbuf};
|
||||
use gtk4::prelude::*;
|
||||
use gtk4::{CheckButton, Image, ListStore, Orientation, ScrolledWindow, TreeIter, TreeModel, TreePath, TreeSelection, Widget};
|
||||
use gtk4::{Align, CheckButton, Image, ListStore, Orientation, ScrolledWindow, TreeIter, TreeModel, TreePath, TreeSelection, Widget};
|
||||
use image::DynamicImage;
|
||||
|
||||
use crate::flg;
|
||||
use crate::gui_structs::gui_data::GuiData;
|
||||
use crate::help_functions::{count_number_of_groups, get_all_children, get_full_name_from_path_name, get_max_file_name, resize_pixbuf_dimension, NotebookObject, NOTEBOOKS_INFOS};
|
||||
use crate::help_functions::{
|
||||
count_number_of_groups, get_all_children, get_full_name_from_path_name, get_max_file_name, get_pixbuf_from_dynamic_image, resize_pixbuf_dimension, NotebookObject,
|
||||
NOTEBOOKS_INFOS,
|
||||
};
|
||||
use crate::localizer_core::generate_translation_hashmap;
|
||||
|
||||
const BIG_PREVIEW_SIZE: i32 = 600;
|
||||
const SMALL_PREVIEW_SIZE: i32 = 100;
|
||||
const SMALL_PREVIEW_SIZE: i32 = 130;
|
||||
|
||||
pub fn connect_button_compare(gui_data: &GuiData) {
|
||||
let button_compare = gui_data.bottom_buttons.buttons_compare.clone();
|
||||
|
@ -88,7 +95,6 @@ pub fn connect_button_compare(gui_data: &GuiData) {
|
|||
let image_compare_left = gui_data.compare_images.image_compare_left.clone();
|
||||
let image_compare_right = gui_data.compare_images.image_compare_right.clone();
|
||||
window_compare.connect_close_request(move |window_compare| {
|
||||
// TODO GTK4
|
||||
window_compare.hide();
|
||||
*shared_image_cache.borrow_mut() = Vec::new();
|
||||
*shared_current_path.borrow_mut() = None;
|
||||
|
@ -347,9 +353,64 @@ fn generate_cache_for_results(vector_with_path: Vec<(String, String, TreePath)>)
|
|||
let small_img = Image::new();
|
||||
let big_img = Image::new();
|
||||
|
||||
let mut pixbuf = get_pixbuf_from_dynamic_image(&DynamicImage::new_rgb8(1, 1)).unwrap();
|
||||
let name_lowercase = name.to_lowercase();
|
||||
let is_heic = HEIC_EXTENSIONS.iter().any(|extension| name_lowercase.ends_with(extension));
|
||||
let is_webp = name.to_lowercase().ends_with(".webp");
|
||||
|
||||
if is_heic || is_webp {
|
||||
#[allow(clippy::never_loop)]
|
||||
'czystka: loop {
|
||||
#[cfg(feature = "heif")]
|
||||
if is_heic {
|
||||
match get_dynamic_image_from_heic(&full_path) {
|
||||
Ok(t) => {
|
||||
match get_pixbuf_from_dynamic_image(&t) {
|
||||
Ok(t) => {
|
||||
pixbuf = t;
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to open image {}, reason {}", full_path, e);
|
||||
}
|
||||
};
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to open image {}, reason {}", full_path, e);
|
||||
}
|
||||
};
|
||||
break 'czystka;
|
||||
}
|
||||
if is_webp {
|
||||
match image::open(&full_path) {
|
||||
Ok(t) => {
|
||||
match get_pixbuf_from_dynamic_image(&t) {
|
||||
Ok(t) => {
|
||||
pixbuf = t;
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to open image {}, reason {}", full_path, e);
|
||||
}
|
||||
};
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to open image {}, reason {}", full_path, e);
|
||||
}
|
||||
};
|
||||
break 'czystka;
|
||||
}
|
||||
break 'czystka;
|
||||
}
|
||||
} else {
|
||||
match Pixbuf::from_file(&full_path) {
|
||||
Ok(pixbuf) =>
|
||||
{
|
||||
Ok(t) => {
|
||||
pixbuf = t;
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to open image {}, reason {}", full_path, e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[allow(clippy::never_loop)]
|
||||
loop {
|
||||
let pixbuf_big = match resize_pixbuf_dimension(pixbuf, (BIG_PREVIEW_SIZE, BIG_PREVIEW_SIZE), InterpType::Nearest) {
|
||||
|
@ -371,11 +432,6 @@ fn generate_cache_for_results(vector_with_path: Vec<(String, String, TreePath)>)
|
|||
small_img.set_from_pixbuf(Some(&pixbuf_small));
|
||||
break;
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to open image {}, reason {}", full_path, e);
|
||||
}
|
||||
};
|
||||
|
||||
cache_all_images.push((full_path, name, big_img, small_img, tree_path));
|
||||
}
|
||||
|
@ -474,10 +530,11 @@ fn populate_similar_scrolled_view(
|
|||
column_selection: i32,
|
||||
) {
|
||||
scrolled_window.set_child(None::<&Widget>);
|
||||
scrolled_window.set_propagate_natural_height(true);
|
||||
|
||||
let all_gtk_box = gtk4::Box::new(Orientation::Horizontal, 5);
|
||||
all_gtk_box.set_widget_name("all_box");
|
||||
all_gtk_box.set_halign(Align::Fill);
|
||||
all_gtk_box.set_valign(Align::Fill);
|
||||
|
||||
for (number, (path, _name, big_thumbnail, small_thumbnail, tree_path)) in image_cache.iter().enumerate() {
|
||||
let small_box = gtk4::Box::new(Orientation::Vertical, 3);
|
||||
|
@ -534,6 +591,17 @@ fn populate_similar_scrolled_view(
|
|||
smaller_box.append(&button_right);
|
||||
|
||||
small_box.append(&smaller_box);
|
||||
small_box.set_halign(Align::Fill);
|
||||
small_box.set_valign(Align::Fill);
|
||||
small_box.set_hexpand_set(true);
|
||||
small_box.set_vexpand_set(true);
|
||||
small_thumbnail.set_halign(Align::Fill);
|
||||
small_thumbnail.set_valign(Align::Fill);
|
||||
small_thumbnail.set_hexpand(true);
|
||||
small_thumbnail.set_hexpand_set(true);
|
||||
small_thumbnail.set_vexpand(true);
|
||||
small_thumbnail.set_vexpand_set(true);
|
||||
|
||||
small_box.append(small_thumbnail);
|
||||
|
||||
all_gtk_box.append(&small_box);
|
||||
|
|
|
@ -3,8 +3,12 @@ use std::collections::HashMap;
|
|||
use std::path::PathBuf;
|
||||
|
||||
use gdk4::gdk_pixbuf::{InterpType, Pixbuf};
|
||||
use glib::Error;
|
||||
use gtk4::prelude::*;
|
||||
use gtk4::{ListStore, TextView, TreeView, Widget};
|
||||
use image::codecs::jpeg::JpegEncoder;
|
||||
use image::{DynamicImage, EncodableLayout};
|
||||
use once_cell::sync::OnceCell;
|
||||
|
||||
use czkawka_core::bad_extensions::BadExtensions;
|
||||
use czkawka_core::big_file::BigFile;
|
||||
|
@ -857,3 +861,16 @@ pub fn set_icon_of_button<P: IsA<Widget>>(button: &P, data: &'static [u8]) {
|
|||
let pixbuf = pixbuf.scale_simple(SIZE_OF_ICON, SIZE_OF_ICON, TYPE_OF_INTERPOLATION).unwrap();
|
||||
image.set_from_pixbuf(Some(&pixbuf));
|
||||
}
|
||||
|
||||
static mut IMAGE_PREVIEW_ARRAY: OnceCell<Vec<u8>> = OnceCell::new();
|
||||
pub fn get_pixbuf_from_dynamic_image(dynamic_image: &DynamicImage) -> Result<Pixbuf, Error> {
|
||||
let mut output = Vec::new();
|
||||
JpegEncoder::new(&mut output).encode_image(dynamic_image).unwrap();
|
||||
let arra;
|
||||
unsafe {
|
||||
IMAGE_PREVIEW_ARRAY.take();
|
||||
IMAGE_PREVIEW_ARRAY.set(output).unwrap();
|
||||
arra = IMAGE_PREVIEW_ARRAY.get().unwrap().as_bytes();
|
||||
}
|
||||
Pixbuf::from_read(arra)
|
||||
}
|
||||
|
|
|
@ -8,7 +8,9 @@ use gtk4::gdk_pixbuf::InterpType;
|
|||
use gtk4::prelude::*;
|
||||
use gtk4::{CheckButton, Image, SelectionMode, TextView, TreeView};
|
||||
|
||||
use czkawka_core::common::{IMAGE_RS_EXTENSIONS, RAW_IMAGE_EXTENSIONS};
|
||||
#[cfg(feature = "heif")]
|
||||
use czkawka_core::common::get_dynamic_image_from_heic;
|
||||
use czkawka_core::common::{HEIC_EXTENSIONS, IMAGE_RS_EXTENSIONS, RAW_IMAGE_EXTENSIONS};
|
||||
use czkawka_core::similar_images::SIMILAR_VALUES;
|
||||
use czkawka_core::similar_videos::MAX_TOLERANCE;
|
||||
|
||||
|
@ -699,16 +701,73 @@ fn show_preview(
|
|||
}
|
||||
}
|
||||
|
||||
let is_heic;
|
||||
let is_webp;
|
||||
if let Some(extension) = Path::new(&name).extension() {
|
||||
let extension = format!(".{}", extension.to_string_lossy().to_lowercase());
|
||||
if !RAW_IMAGE_EXTENSIONS.contains(&extension.as_str()) && !IMAGE_RS_EXTENSIONS.contains(&extension.as_str()) {
|
||||
is_heic = HEIC_EXTENSIONS.contains(&extension.as_str());
|
||||
is_webp = ".webp" == extension;
|
||||
if !RAW_IMAGE_EXTENSIONS.contains(&extension.as_str()) && !IMAGE_RS_EXTENSIONS.contains(&extension.as_str()) && !is_heic {
|
||||
break 'dir;
|
||||
}
|
||||
} else {
|
||||
break 'dir;
|
||||
}
|
||||
let mut pixbuf = if is_heic || is_webp {
|
||||
let image = if is_heic {
|
||||
#[cfg(feature = "heif")]
|
||||
match get_dynamic_image_from_heic(file_name) {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
add_text_to_text_view(
|
||||
text_view_errors,
|
||||
flg!(
|
||||
"preview_image_opening_failure",
|
||||
generate_translation_hashmap(vec![("name", file_name.to_string()), ("reason", e.to_string())])
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
break 'dir;
|
||||
}
|
||||
}
|
||||
|
||||
let mut pixbuf = match Pixbuf::from_file(file_name) {
|
||||
#[cfg(not(feature = "heif"))]
|
||||
panic!("")
|
||||
} else if is_webp {
|
||||
match image::open(file_name) {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
add_text_to_text_view(
|
||||
text_view_errors,
|
||||
flg!(
|
||||
"preview_image_opening_failure",
|
||||
generate_translation_hashmap(vec![("name", file_name.to_string()), ("reason", e.to_string())])
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
break 'dir;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
panic!("");
|
||||
};
|
||||
|
||||
match get_pixbuf_from_dynamic_image(&image) {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
add_text_to_text_view(
|
||||
text_view_errors,
|
||||
flg!(
|
||||
"preview_image_opening_failure",
|
||||
generate_translation_hashmap(vec![("name", file_name.to_string()), ("reason", e.to_string())])
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
break 'dir;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match Pixbuf::from_file(file_name) {
|
||||
Ok(pixbuf) => pixbuf,
|
||||
Err(e) => {
|
||||
add_text_to_text_view(
|
||||
|
@ -721,6 +780,7 @@ fn show_preview(
|
|||
);
|
||||
break 'dir;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pixbuf = match resize_pixbuf_dimension(pixbuf, (800, 800), InterpType::Nearest) {
|
||||
|
|
|
@ -11,14 +11,7 @@
|
|||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="label_group_info">
|
||||
<property name="halign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="label" translatable="yes">Group XD/PER XD (99 images in current group)</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button_go_next_compare_group">
|
||||
<object class="GtkButton" id="button_go_previous_compare_group">
|
||||
<property name="focusable">1</property>
|
||||
<property name="receives-default">1</property>
|
||||
<child>
|
||||
|
@ -29,7 +22,14 @@
|
|||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button_go_previous_compare_group">
|
||||
<object class="GtkLabel" id="label_group_info">
|
||||
<property name="halign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="label" translatable="yes">Group XD/PER XD (99 images in current group)</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button_go_next_compare_group">
|
||||
<property name="focusable">1</property>
|
||||
<property name="receives-default">1</property>
|
||||
<child>
|
||||
|
@ -63,16 +63,22 @@
|
|||
<property name="homogeneous">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image_compare_left"/>
|
||||
<object class="GtkImage" id="image_compare_left">
|
||||
<property name="height-request">100</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="image_compare_right"/>
|
||||
<object class="GtkImage" id="image_compare_right">
|
||||
<property name="height-request">100</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolled_window_compare_choose_images">
|
||||
<property name="focusable">1</property>
|
||||
<property name="max-content-height">150</property>
|
||||
<property name="min-content-height">150</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
@ -24,10 +24,10 @@
|
|||
(4,1,"GtkDialog","window_compare",None,None,None,None,None),
|
||||
(4,2,"GtkBox",None,1,None,None,None,None),
|
||||
(4,3,"GtkBox",None,2,None,None,None,None),
|
||||
(4,4,"GtkLabel","label_group_info",3,None,None,None,None),
|
||||
(4,5,"GtkButton","button_go_next_compare_group",3,None,None,None,1),
|
||||
(4,4,"GtkLabel","label_group_info",3,None,None,None,1),
|
||||
(4,5,"GtkButton","button_go_next_compare_group",3,None,None,None,2),
|
||||
(4,6,"GtkImage",None,5,None,None,None,None),
|
||||
(4,7,"GtkButton","button_go_previous_compare_group",3,None,None,None,2),
|
||||
(4,7,"GtkButton","button_go_previous_compare_group",3,None,None,None,None),
|
||||
(4,8,"GtkImage",None,7,None,None,None,None),
|
||||
(4,9,"GtkBox",None,2,None,None,None,1),
|
||||
(4,10,"GtkCheckButton","check_button_left_preview_text",9,None,None,None,None),
|
||||
|
@ -260,8 +260,6 @@
|
|||
(8,26,"GtkLabel",None,24,None,None,None,1),
|
||||
(9,1,"GtkDialog","window_settings",None,None,None,None,None),
|
||||
(9,3,"GtkBox","potatoo",1,None,None,None,None),
|
||||
(9,4,"GtkBox",None,3,None,None,None,None),
|
||||
(9,5,"GtkComboBoxText",None,4,None,None,None,None),
|
||||
(9,6,"GtkNotebook","notebook_settings",3,None,None,None,1),
|
||||
(9,7,"GtkNotebookPage",None,6,None,None,None,None),
|
||||
(9,8,"GtkBox",None,7,None,None,None,None),
|
||||
|
@ -336,6 +334,10 @@
|
|||
(4,11,"GtkWidget","focusable","1",None,None,None,None,None),
|
||||
(4,12,"GtkBox","homogeneous","1",None,None,None,None,None),
|
||||
(4,12,"GtkWidget","vexpand","1",None,None,None,None,None),
|
||||
(4,13,"GtkWidget","height-request","100",None,None,None,None,None),
|
||||
(4,14,"GtkWidget","height-request","100",None,None,None,None,None),
|
||||
(4,15,"GtkScrolledWindow","max-content-height","150",None,None,None,None,None),
|
||||
(4,15,"GtkScrolledWindow","min-content-height","150",None,None,None,None,None),
|
||||
(4,15,"GtkWidget","focusable","1",None,None,None,None,None),
|
||||
(5,1,"GtkAdjustment","page-increment","10",None,None,None,None,None),
|
||||
(5,1,"GtkAdjustment","step-increment","1",None,None,None,None,None),
|
||||
|
@ -803,8 +805,6 @@
|
|||
(9,1,"GtkWindow","title","Czkawka Options",1,None,None,None,None),
|
||||
(9,3,"GtkOrientable","orientation","vertical",None,None,None,None,None),
|
||||
(9,3,"GtkWidget","vexpand","1",None,None,None,None,None),
|
||||
(9,4,"GtkOrientable","orientation","vertical",None,None,None,None,None),
|
||||
(9,5,"GtkWidget","valign","center",None,None,None,None,None),
|
||||
(9,6,"GtkNotebook","tab-pos","left",None,None,None,None,None),
|
||||
(9,6,"GtkWidget","focusable","1",None,None,None,None,None),
|
||||
(9,6,"GtkWidget","vexpand","1",None,None,None,None,None),
|
||||
|
|
|
@ -10,16 +10,6 @@
|
|||
<object class="GtkBox" id="potatoo">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkComboBoxText">
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkNotebook" id="notebook_settings">
|
||||
<property name="focusable">1</property>
|
||||
|
|
|
@ -6,6 +6,8 @@ If you only want the terminal version without a GUI, just skip all the packages
|
|||
|
||||
FFmpeg is not included here because it is not needed to build - it is dynamically loaded.
|
||||
|
||||
Support for heif images is optional and require to install libheif library.
|
||||
|
||||
|
||||
| Program | Min | What for |
|
||||
|---------|------|-------------------------------------------------------------------------------|
|
||||
|
@ -26,12 +28,12 @@ sudo yum install gtk3-devel glib2-devel
|
|||
```
|
||||
|
||||
#### macOS
|
||||
You need to install Rust via Homebrew and GTK Libraries
|
||||
You need to install Rust via Homebrew, GTK Libraries and optionally heif library(to have support for heic files, which are quite popular on mac)
|
||||
```shell
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
brew install rustup
|
||||
rustup-init
|
||||
brew install gtk+3 adwaita-icon-theme librsvg
|
||||
brew install gtk+3 adwaita-icon-theme librsvg libheif
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
|
|
@ -29,7 +29,7 @@ One very straight-forward way to do this is by using [Homebrew](https://brew.sh/
|
|||
Installation in the terminal:
|
||||
```shell
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
brew install gtk+3 adwaita-icon-theme ffmpeg librsvg
|
||||
brew install gtk+3 adwaita-icon-theme ffmpeg librsvg libheif
|
||||
```
|
||||
After that, go to the location where you downloaded Czkawka and add the `executable` permission to this file.
|
||||
```shell
|
||||
|
@ -43,7 +43,7 @@ At the end execute it:
|
|||
**Warning**
|
||||
Prebuilt binaries are available only for x86_64, so if you use ARM machine like e.g. Mac M1, you need to compile manually app or install special version of required libraries which can be done via this:
|
||||
```shell
|
||||
arch -x86_64 /usr/local/bin/brew install gtk+3 adwaita-icon-theme ffmpeg librsvg
|
||||
arch -x86_64 /usr/local/bin/brew install gtk+3 adwaita-icon-theme ffmpeg librsvg libheif
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name: czkawka # you probably want to 'snapcraft register <name>'
|
||||
base: core20 # the base snap is the execution environment for this snap
|
||||
base: core22 # the base snap is the execution environment for this snap
|
||||
version: '4.1.0' # just for humans, typically '1.2+git' or '1.3.2'
|
||||
summary: Czkawka - fast data cleaner written in Rust # 79 char long summary
|
||||
description: |
|
||||
|
|
Loading…
Reference in a new issue