feat: kra (krita) support
This commit is contained in:
parent
2e8a6c8546
commit
fc92ff60e0
3 changed files with 430 additions and 33 deletions
139
src/utils.rs
139
src/utils.rs
|
|
@ -1,50 +1,123 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::{
|
||||
fs,
|
||||
io::{self, Read},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use iced::widget;
|
||||
use image::{DynamicImage, ImageDecoder, ImageReader, RgbaImage};
|
||||
use rfd::FileDialog;
|
||||
use zip::ZipArchive;
|
||||
|
||||
pub fn load_image(path: impl AsRef<Path>) -> Result<RgbaImage, String> {
|
||||
let path = path.as_ref();
|
||||
|
||||
let reader = match ImageReader::open(path) {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
let decoded_image = if path.extension().is_some_and(|ext| ext == "kra") {
|
||||
let reader = match fs::File::open(path).map(io::BufReader::new) {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
return Err(format!(
|
||||
"failed to create reader for '{}': {e}",
|
||||
path.display()
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let mut zip = match ZipArchive::new(reader) {
|
||||
Ok(z) => z,
|
||||
Err(e) => {
|
||||
return Err(format!(
|
||||
"failed to open zip archive '{}': {e}",
|
||||
path.display()
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let mut reader = match zip.by_name("mergedimage.png") {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
return Err(format!(
|
||||
"failed to open file in zip archive '{}': {e}",
|
||||
path.display()
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
// reading it all and wrapping it with a Cursor
|
||||
// is the only way I know to give it Seek
|
||||
// (which is required by ImageReader)
|
||||
let mut buf = Vec::new();
|
||||
if let Err(e) = reader.read_to_end(&mut buf) {
|
||||
return Err(format!(
|
||||
"failed to create reader for '{}': {e}",
|
||||
"error when reading file in zip archive '{}': {e}",
|
||||
path.display()
|
||||
));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
let mut decoder = match reader.into_decoder() {
|
||||
Ok(d) => d,
|
||||
Err(e) => {
|
||||
return Err(format!(
|
||||
"failed to create decoder for '{}': {e}",
|
||||
path.display()
|
||||
));
|
||||
}
|
||||
};
|
||||
let image_reader = ImageReader::with_format(io::Cursor::new(buf), image::ImageFormat::Png);
|
||||
|
||||
let oreintation = match decoder.orientation() {
|
||||
Ok(o) => o,
|
||||
Err(e) => {
|
||||
return Err(format!(
|
||||
"failed to get oreintation of '{}': {e}",
|
||||
path.display()
|
||||
));
|
||||
}
|
||||
};
|
||||
let decoder = match image_reader.into_decoder() {
|
||||
Ok(d) => d,
|
||||
Err(e) => {
|
||||
return Err(format!(
|
||||
"failed to create decoder for '{}': {e}",
|
||||
path.display()
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let mut decoded_image = match DynamicImage::from_decoder(decoder) {
|
||||
Ok(i) => i,
|
||||
Err(e) => {
|
||||
return Err(format!("failed to decode image '{}': {e}", path.display()));
|
||||
}
|
||||
};
|
||||
let decoded_image = match DynamicImage::from_decoder(decoder) {
|
||||
Ok(i) => i,
|
||||
Err(e) => {
|
||||
return Err(format!("failed to decode image '{}': {e}", path.display()));
|
||||
}
|
||||
};
|
||||
|
||||
decoded_image.apply_orientation(oreintation);
|
||||
decoded_image
|
||||
} else {
|
||||
let image_reader = match ImageReader::open(path) {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
return Err(format!(
|
||||
"failed to create image reader for '{}': {e}",
|
||||
path.display()
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let mut decoder = match image_reader.into_decoder() {
|
||||
Ok(d) => d,
|
||||
Err(e) => {
|
||||
return Err(format!(
|
||||
"failed to create decoder for '{}': {e}",
|
||||
path.display()
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
// we don't need to check this for the kra branch
|
||||
// since PNGs don't have metadata oreintation
|
||||
let oreintation = match decoder.orientation() {
|
||||
Ok(o) => o,
|
||||
Err(e) => {
|
||||
return Err(format!(
|
||||
"failed to get oreintation of '{}': {e}",
|
||||
path.display()
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let mut decoded_image = match DynamicImage::from_decoder(decoder) {
|
||||
Ok(i) => i,
|
||||
Err(e) => {
|
||||
return Err(format!("failed to decode image '{}': {e}", path.display()));
|
||||
}
|
||||
};
|
||||
|
||||
decoded_image.apply_orientation(oreintation);
|
||||
|
||||
decoded_image
|
||||
};
|
||||
|
||||
Ok(decoded_image.into_rgba8())
|
||||
}
|
||||
|
|
@ -54,7 +127,7 @@ pub fn pick_image() -> Result<PathBuf, String> {
|
|||
"image",
|
||||
&[
|
||||
"png", "PNG", "jpg", "JPG", "jpeg", "JPEG", "avif", "jxl", "bmp", "exr", "ff",
|
||||
"gif", "hdr", "ico", "pnm", "qoi", "tga", "tiff", "webp",
|
||||
"gif", "hdr", "ico", "pnm", "qoi", "tga", "tiff", "webp", "kra",
|
||||
],
|
||||
)
|
||||
.pick_file()
|
||||
|
|
|
|||
Loading…
Reference in a new issue