added: Save

Left: Config
This commit is contained in:
Piyush मिश्रः 2022-01-13 19:28:34 +05:30
parent 6517773cf3
commit 278cffd925
8 changed files with 160 additions and 7 deletions

View File

@ -0,0 +1 @@
{"path":"/home/piyush/Projects/post_maker/75e253532946877dea6aaa5a60ffd51a.jpg","dimension":[400.0,500.0],"original_dimension":[720.0,1280.0],"crop_position":[0.0,190.0],"quote":"wow!","tag":"","quote_position":853.3333333333334,"tag_position":853.3333333333334,"rgba":[25,29,34,190],"is_saved":false}

View File

Before

Width:  |  Height:  |  Size: 198 KiB

After

Width:  |  Height:  |  Size: 198 KiB

View File

@ -0,0 +1 @@
{"path":"/home/piyush/Projects/post_maker/bearbrickjia-20211228-0002.jpg","dimension":[400.0,500.0],"original_dimension":[1440.0,1124.0],"crop_position":[270.4,0.0],"quote":"hello","tag":"","quote_position":749.3333333333334,"tag_position":749.3333333333334,"rgba":[25,29,34,190],"is_saved":false}

View File

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 132 KiB

View File

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 124 KiB

View File

@ -26,6 +26,7 @@ pub(crate) enum DrawMessage {
ChangeCrop((f64, f64)), ChangeCrop((f64, f64)),
Recalc, Recalc,
Flush, Flush,
Save,
} }
pub(crate) fn spawn_image_thread( pub(crate) fn spawn_image_thread(
@ -98,6 +99,13 @@ pub(crate) fn spawn_image_thread(
DrawMessage::Flush => { DrawMessage::Flush => {
flush_buffer(&app_sender, &mut _container); flush_buffer(&app_sender, &mut _container);
} }
DrawMessage::Save => {
if let Some(cont) = &mut _container {
status.set_label("Saving...");
cont.save();
status.set_label("");
}
}
} }
} }
}); });
@ -154,6 +162,7 @@ fn load_image(
prop.quote_position = saved_prop.quote_position; prop.quote_position = saved_prop.quote_position;
prop.tag_position = saved_prop.quote_position; prop.tag_position = saved_prop.quote_position;
prop.rgba = saved_prop.rgba; prop.rgba = saved_prop.rgba;
prop.is_saved = true;
use_defaults = false; use_defaults = false;
let saved = prop.is_saved; let saved = prop.is_saved;
drop(prop); drop(prop);
@ -173,7 +182,6 @@ fn load_image(
if use_defaults { if use_defaults {
let mut prop = properties.write().unwrap(); let mut prop = properties.write().unwrap();
prop.quote = "".to_owned(); prop.quote = "".to_owned();
quote_position.set_range(0.0, prop.original_dimension.1); quote_position.set_range(0.0, prop.original_dimension.1);
quote_position.set_value(prop.quote_position); quote_position.set_value(prop.quote_position);
tag_position.set_range(0.0, prop.original_dimension.1); tag_position.set_range(0.0, prop.original_dimension.1);
@ -185,11 +193,18 @@ fn load_image(
layer_blue.value() as u8, layer_blue.value() as u8,
layer_alpha.value() as u8, layer_alpha.value() as u8,
]; ];
drop(prop);
match crop { match crop {
Some((x, y)) => cont.apply_crop_pos(x, y), Some((x, y)) => {
None => cont.apply_crop(), prop.is_saved = false;
drop(prop);
cont.apply_crop_pos(x, y);
}
None => {
prop.is_saved = true;
drop(prop);
cont.apply_crop();
}
} }
} }

View File

@ -254,11 +254,12 @@ impl MainWindow {
}, },
); );
let sender = self.sender.clone();
self.menubar.add( self.menubar.add(
"&File/Save...\t", "&File/Save...\t",
Shortcut::Ctrl | 's', Shortcut::Ctrl | 's',
menu::MenuFlag::Normal, menu::MenuFlag::Normal,
|_| {}, move |_| sender.send(DrawMessage::Save).unwrap(),
); );
self.menubar.add( self.menubar.add(
@ -290,21 +291,37 @@ impl MainWindow {
} }
fn events(&mut self) { fn events(&mut self) {
let sender = self.sender.clone();
self.save_btn
.set_callback(move |_| sender.send(DrawMessage::Save).unwrap());
let properties = Arc::clone(&self.properties); let properties = Arc::clone(&self.properties);
let mut crop_win = CropWindow::new(); let mut crop_win = CropWindow::new();
let sender = self.sender.clone(); let sender = self.sender.clone();
self.crop_btn.set_callback(move |_| { self.crop_btn.set_callback(move |_| {
let prop = properties.read().unwrap(); let mut prop = properties.write().unwrap();
if let Some(path) = &prop.path { if let Some(path) = &prop.path {
if let Some((x, y)) = crop_win.load_to_crop(path, prop.crop_position) { if let Some((x, y)) = crop_win.load_to_crop(path, prop.crop_position) {
sender.send(DrawMessage::ChangeCrop((x, y))).unwrap(); sender.send(DrawMessage::ChangeCrop((x, y))).unwrap();
prop.is_saved = false;
} }
} }
}); });
let mut file_choice = self.file_choice.clone(); let mut file_choice = self.file_choice.clone();
let sender = self.sender.clone(); let sender = self.sender.clone();
let properties = Arc::clone(&self.properties);
self.next_btn.set_callback(move |_| { self.next_btn.set_callback(move |_| {
let prop = properties.read().unwrap();
if !prop.is_saved {
let save = fltk::dialog::choice_default("Save?", "yes", "no", "cancel");
match save {
0 => sender.send(DrawMessage::Save).unwrap(),
1 => {}
_ => return,
}
}
if file_choice.value() == file_choice.size() - 2 { if file_choice.value() == file_choice.size() - 2 {
file_choice.set_value(0); file_choice.set_value(0);
} else { } else {
@ -315,7 +332,18 @@ impl MainWindow {
let mut file_choice = self.file_choice.clone(); let mut file_choice = self.file_choice.clone();
let sender = self.sender.clone(); let sender = self.sender.clone();
let properties = Arc::clone(&self.properties);
self.back_btn.set_callback(move |_| { self.back_btn.set_callback(move |_| {
let prop = properties.read().unwrap();
if !prop.is_saved {
let save = fltk::dialog::choice_default("Save?", "yes", "no", "cancel");
match save {
0 => sender.send(DrawMessage::Save).unwrap(),
1 => {}
_ => return,
}
}
if file_choice.value() == 0 { if file_choice.value() == 0 {
file_choice.set_value(file_choice.size() - 2); file_choice.set_value(file_choice.size() - 2);
} else { } else {
@ -325,7 +353,17 @@ impl MainWindow {
}); });
let sender = self.sender.clone(); let sender = self.sender.clone();
let properties = Arc::clone(&self.properties);
self.file_choice.set_callback(move |_| { self.file_choice.set_callback(move |_| {
let prop = properties.read().unwrap();
if !prop.is_saved {
let save = fltk::dialog::choice_default("Save?", "yes", "no", "cancel");
match save {
0 => sender.send(DrawMessage::Save).unwrap(),
1 => {}
_ => return,
}
}
sender.send(DrawMessage::Open).unwrap(); sender.send(DrawMessage::Open).unwrap();
}); });
@ -336,6 +374,7 @@ impl MainWindow {
if ev == enums::Event::KeyUp { if ev == enums::Event::KeyUp {
let mut prop = properties.write().unwrap(); let mut prop = properties.write().unwrap();
prop.quote = f.value(); prop.quote = f.value();
prop.is_saved = false;
sender.send(DrawMessage::Recalc).unwrap(); sender.send(DrawMessage::Recalc).unwrap();
sender.send(DrawMessage::Flush).unwrap(); sender.send(DrawMessage::Flush).unwrap();
image.redraw(); image.redraw();
@ -350,6 +389,7 @@ impl MainWindow {
if ev == enums::Event::KeyUp { if ev == enums::Event::KeyUp {
let mut prop = properties.write().unwrap(); let mut prop = properties.write().unwrap();
prop.tag = f.value(); prop.tag = f.value();
prop.is_saved = false;
sender.send(DrawMessage::Recalc).unwrap(); sender.send(DrawMessage::Recalc).unwrap();
sender.send(DrawMessage::Flush).unwrap(); sender.send(DrawMessage::Flush).unwrap();
image.redraw(); image.redraw();
@ -363,6 +403,7 @@ impl MainWindow {
self.quote_position.set_callback(move |f| { self.quote_position.set_callback(move |f| {
let mut prop = properties.write().unwrap(); let mut prop = properties.write().unwrap();
prop.quote_position = f.value(); prop.quote_position = f.value();
prop.is_saved = false;
sender.send(DrawMessage::Recalc).unwrap(); sender.send(DrawMessage::Recalc).unwrap();
sender.send(DrawMessage::Flush).unwrap(); sender.send(DrawMessage::Flush).unwrap();
image.redraw(); image.redraw();
@ -374,6 +415,7 @@ impl MainWindow {
self.tag_position.set_callback(move |f| { self.tag_position.set_callback(move |f| {
let mut prop = properties.write().unwrap(); let mut prop = properties.write().unwrap();
prop.tag_position = f.value(); prop.tag_position = f.value();
prop.is_saved = false;
sender.send(DrawMessage::Recalc).unwrap(); sender.send(DrawMessage::Recalc).unwrap();
sender.send(DrawMessage::Flush).unwrap(); sender.send(DrawMessage::Flush).unwrap();
image.redraw(); image.redraw();
@ -385,6 +427,7 @@ impl MainWindow {
self.layer_red.set_callback(move |f| { self.layer_red.set_callback(move |f| {
let mut prop = properties.write().unwrap(); let mut prop = properties.write().unwrap();
prop.rgba[0] = f.value() as u8; prop.rgba[0] = f.value() as u8;
prop.is_saved = false;
sender.send(DrawMessage::Recalc).unwrap(); sender.send(DrawMessage::Recalc).unwrap();
sender.send(DrawMessage::Flush).unwrap(); sender.send(DrawMessage::Flush).unwrap();
image.redraw(); image.redraw();
@ -396,6 +439,7 @@ impl MainWindow {
self.layer_green.set_callback(move |f| { self.layer_green.set_callback(move |f| {
let mut prop = properties.write().unwrap(); let mut prop = properties.write().unwrap();
prop.rgba[1] = f.value() as u8; prop.rgba[1] = f.value() as u8;
prop.is_saved = false;
sender.send(DrawMessage::Recalc).unwrap(); sender.send(DrawMessage::Recalc).unwrap();
sender.send(DrawMessage::Flush).unwrap(); sender.send(DrawMessage::Flush).unwrap();
image.redraw(); image.redraw();
@ -407,6 +451,7 @@ impl MainWindow {
self.layer_blue.set_callback(move |f| { self.layer_blue.set_callback(move |f| {
let mut prop = properties.write().unwrap(); let mut prop = properties.write().unwrap();
prop.rgba[2] = f.value() as u8; prop.rgba[2] = f.value() as u8;
prop.is_saved = false;
sender.send(DrawMessage::Recalc).unwrap(); sender.send(DrawMessage::Recalc).unwrap();
sender.send(DrawMessage::Flush).unwrap(); sender.send(DrawMessage::Flush).unwrap();
image.redraw(); image.redraw();
@ -418,6 +463,7 @@ impl MainWindow {
self.layer_alpha.set_callback(move |f| { self.layer_alpha.set_callback(move |f| {
let mut prop = properties.write().unwrap(); let mut prop = properties.write().unwrap();
prop.rgba[3] = f.value() as u8; prop.rgba[3] = f.value() as u8;
prop.is_saved = false;
sender.send(DrawMessage::Recalc).unwrap(); sender.send(DrawMessage::Recalc).unwrap();
sender.send(DrawMessage::Flush).unwrap(); sender.send(DrawMessage::Flush).unwrap();
image.redraw(); image.redraw();

View File

@ -1,4 +1,8 @@
use std::sync::{Arc, RwLock}; use std::{
fs,
path::Path,
sync::{Arc, RwLock},
};
use image::{DynamicImage, GenericImageView, ImageBuffer}; use image::{DynamicImage, GenericImageView, ImageBuffer};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -176,6 +180,92 @@ impl ImageContainer {
self.buffer = tmp; self.buffer = tmp;
} }
pub(crate) fn save(&self) {
let prop = self.properties.read().unwrap();
let path_original = match &prop.path {
Some(p) => Path::new(p),
None => return,
};
let path_conf = path_original.with_extension("conf");
let export = path_original
.parent()
.unwrap()
.join("export")
.join(path_original.file_name().unwrap().to_str().unwrap());
fs::write(&path_conf, serde_json::to_string(&*prop).unwrap()).unwrap();
let mut img = image::open(&path_original).unwrap();
let (width, height): (f64, f64) = Coord::from(img.dimensions()).into();
let (crop_x, crop_y) = prop.crop_position.unwrap();
let (crop_width, crop_height) = get_4_5(width, height);
let mut img = img.crop(
crop_x as u32,
crop_y as u32,
crop_width as u32,
crop_height as u32,
);
let layer = DynamicImage::ImageRgba8(ImageBuffer::from_fn(
crop_width as u32,
crop_height as u32,
|_, _| image::Rgba(prop.rgba),
));
image::imageops::overlay(&mut img, &layer, 0, 0);
let size = quote_from_height(crop_height);
for (index, line) in prop.quote.lines().enumerate() {
let (text_width, text_height) = measure_line(
&properties::FONT_QUOTE,
line,
rusttype::Scale::uniform(size as f32),
);
imageproc::drawing::draw_text_mut(
&mut img,
image::Rgba([255, 255, 255, 255]),
((crop_width - text_width) / 2.0) as u32,
((prop.quote_position * crop_height) / prop.original_dimension.1
+ (text_height / 2.0)
+ index as f64 * (text_height * 1.2)) as u32,
rusttype::Scale::uniform(size as f32),
&properties::FONT_QUOTE,
line,
);
}
let size = tag_from_height(crop_height);
for (index, line) in prop.tag.lines().enumerate() {
let (text_width, text_height) = measure_line(
&properties::FONT_TAG,
line,
rusttype::Scale::uniform(size as f32),
);
imageproc::drawing::draw_text_mut(
&mut img,
image::Rgba([255, 255, 255, 255]),
(crop_width * 0.99 - text_width) as u32,
((prop.tag_position * crop_height) / prop.original_dimension.1
+ (text_height / 2.0)
+ index as f64 * (text_height * 1.2)) as u32,
rusttype::Scale::uniform(size as f32),
&properties::FONT_TAG,
line,
);
}
image::save_buffer(
export,
img.as_rgb8().unwrap().as_raw(),
crop_width as u32,
crop_height as u32,
image::ColorType::Rgb8,
)
.unwrap();
}
} }
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]