Bug fixes:

1) use of windows sub system to avoid terminal
2) use of pathbuf for windows fix
Features:
1) Saving in png file
2) Opening png file
This commit is contained in:
Piyush मिश्रः 2022-01-14 13:02:59 +05:30
parent 3b0c3088fb
commit 303aad16db
5 changed files with 47 additions and 26 deletions

View File

@ -9,12 +9,11 @@ use fltk::{
use image::GenericImageView;
use std::{
cell::RefCell,
path::PathBuf,
rc::Rc,
sync::{Arc, RwLock},
};
static mut PATH: String = String::new();
/// Window to crop the existing image
pub(crate) struct CropWindow {
pub win: Window,
@ -90,13 +89,9 @@ impl CropWindow {
/// Call it to show window to crop image
pub(crate) fn load_to_crop(
&mut self,
path: &str,
path: &PathBuf,
crop_pos: Option<(f64, f64)>,
) -> Option<(f64, f64)> {
unsafe {
PATH = path.to_owned();
}
let mut container =
ImageContainer::new(path, Arc::new(RwLock::new(ImageProperties::new())));
{

View File

@ -15,7 +15,7 @@ use fltk::{
use std::{
fs,
path::Path,
path::{Path, PathBuf},
sync::{mpsc, Arc, RwLock},
};
@ -37,6 +37,8 @@ pub(crate) fn spawn_image_thread(
main_win: &MainWindow,
) {
let mut file_choice = main_win.file_choice.clone();
let mut next_btn = main_win.next_btn.clone();
let mut back_btn = main_win.back_btn.clone();
let mut quote = main_win.quote.clone();
let mut tag = main_win.tag.clone();
let mut layer_red = main_win.layer_red.clone();
@ -47,6 +49,7 @@ pub(crate) fn spawn_image_thread(
let mut tag_position = main_win.tag_position.clone();
let mut page = main_win.page.clone();
let mut status = main_win.status.clone();
let images_path = Arc::clone(&main_win.images_path);
let mut _container: Option<ImageContainer> = None;
std::thread::spawn(move || loop {
@ -56,6 +59,7 @@ pub(crate) fn spawn_image_thread(
status.set_label("Loading...");
load_image(
&mut file_choice,
Arc::clone(&images_path),
None,
&mut quote,
&mut tag,
@ -74,8 +78,12 @@ pub(crate) fn spawn_image_thread(
}
DrawMessage::ChangeCrop((x, y)) => {
status.set_label("Loading...");
file_choice.deactivate();
next_btn.deactivate();
back_btn.deactivate();
load_image(
&mut file_choice,
Arc::clone(&images_path),
Some((x, y)),
&mut quote,
&mut tag,
@ -90,6 +98,9 @@ pub(crate) fn spawn_image_thread(
&properties,
&mut _container,
);
file_choice.activate();
next_btn.activate();
back_btn.activate();
status.set_label("");
}
DrawMessage::Recalc => {
@ -114,6 +125,7 @@ pub(crate) fn spawn_image_thread(
fn load_image(
file_choice: &mut menu::Choice,
images_path: Arc<RwLock<Vec<PathBuf>>>,
crop: Option<(f64, f64)>,
quote: &mut MultilineInput,
tag: &mut Input,
@ -128,10 +140,8 @@ fn load_image(
properties: &Arc<RwLock<ImageProperties>>,
container: &mut Option<ImageContainer>,
) {
let file: String = match file_choice.choice() {
Some(val) => val,
None => return,
};
let imgs = images_path.read().unwrap();
let file = imgs.get(file_choice.value() as usize).unwrap();
*container = Some(ImageContainer::new(&file, Arc::clone(properties)));

View File

@ -1,3 +1,5 @@
#![windows_subsystem = "windows"]
mod config;
mod config_window;
mod crop_window;

View File

@ -17,6 +17,7 @@ use fltk::{
prelude::*,
window::Window,
};
use std::path::PathBuf;
use std::sync::{mpsc, RwLock};
use std::{ffi::OsStr, fs, sync::Arc};
@ -41,6 +42,7 @@ pub(crate) struct MainWindow {
pub(crate) crop_btn: Button,
pub(crate) status: Frame,
pub(crate) page: Page,
pub(crate) images_path: Arc<RwLock<Vec<PathBuf>>>,
pub(crate) draw_buff: Arc<RwLock<Vec<u8>>>,
pub(crate) properties: Arc<RwLock<ImageProperties>>,
pub(crate) sender: mpsc::Sender<DrawMessage>,
@ -206,6 +208,7 @@ impl MainWindow {
reset_tag_position_btn,
crop_btn,
status,
images_path: Arc::new(RwLock::new(vec![])),
draw_buff,
properties: Arc::clone(&properties),
page: Page {
@ -226,6 +229,7 @@ impl MainWindow {
let mut file_choice = self.file_choice.clone();
let sender = self.sender.clone();
let mut win = self.win.clone();
let imgs = Arc::clone(&self.images_path);
self.menubar.add(
"&File/Open Folder...\t",
Shortcut::Ctrl | 'o',
@ -249,11 +253,16 @@ impl MainWindow {
}
let files = fs::read_dir(&path).unwrap();
let mut text = String::new();
let mut imgs_b = imgs.write().unwrap();
*imgs_b = vec![];
for file in files {
let file = file.unwrap();
let path = file.path();
if path.extension() == Some(OsStr::new("jpg")) {
text = format!("{}|{}", text, path.to_str().unwrap());
if path.extension() == Some(OsStr::new("jpg"))
|| path.extension() == Some(OsStr::new("png"))
{
text = format!("{}|{}", text, path.file_name().unwrap().to_str().unwrap());
imgs_b.push(path);
}
}
if text.len() == 0 {

View File

@ -1,9 +1,10 @@
use std::{
fs,
path::Path,
path::{Path, PathBuf},
sync::{Arc, RwLock},
};
use fltk::dialog;
use image::{DynamicImage, GenericImageView, ImageBuffer};
use serde::{Deserialize, Serialize};
@ -55,8 +56,16 @@ pub(crate) struct ImageContainer {
}
impl ImageContainer {
pub(crate) fn new(path: &str, properties: Arc<RwLock<ImageProperties>>) -> Self {
let img = image::open(path).unwrap();
pub(crate) fn new(path: &PathBuf, properties: Arc<RwLock<ImageProperties>>) -> Self {
let img = match image::open(path) {
Ok(i) => i,
Err(_) => {
dialog::message_default("Failed to open image");
panic!("Failed to open image");
}
};
let img = DynamicImage::ImageRgb8(img.into_rgb8());
let (width, height): (f64, f64) = Coord::from(img.dimensions()).into();
let (width, height) = (width, height);
@ -178,20 +187,16 @@ impl ImageContainer {
prop.tag_position,
prop.original_dimension.1,
);
image::save_buffer(
export,
img.as_rgb8().unwrap().as_raw(),
crop_width as u32,
crop_height as u32,
image::ColorType::Rgb8,
)
.unwrap();
if let Err(_) = img.save_with_format(&export, image::ImageFormat::Png) {
dialog::message_default("Failed to save!");
}
}
}
#[derive(Serialize, Deserialize, Debug)]
pub(crate) struct ImageProperties {
pub(crate) path: Option<String>,
pub(crate) path: Option<PathBuf>,
pub(crate) dimension: (f64, f64),
pub(crate) original_dimension: (f64, f64),
pub(crate) crop_position: Option<(f64, f64)>,