72 lines
2.6 KiB
Rust
72 lines
2.6 KiB
Rust
use crate::api::models::{MotivationGenerator, PicOxError};
|
|
use log::info;
|
|
use magick_rust::{DrawingWand, MagickWand, PixelWand};
|
|
|
|
pub fn generate_motivation_image(
|
|
motivation: &MotivationGenerator,
|
|
motivation_image_blob: Vec<u8>,
|
|
) -> Result<Vec<u8>, PicOxError> {
|
|
let start_time = std::time::Instant::now();
|
|
|
|
let top_text = format!("{} {}", motivation.action, motivation.goal);
|
|
|
|
let mut wand = MagickWand::new();
|
|
let mut border_wand = PixelWand::new();
|
|
wand.read_image_blob(motivation_image_blob)?;
|
|
|
|
border_wand.set_color(&motivation.border_color)?;
|
|
let width = wand.get_image_width();
|
|
let border = width / 100;
|
|
wand.border_image(
|
|
&border_wand,
|
|
border,
|
|
border,
|
|
magick_rust::bindings::CompositeOperator_OverCompositeOp.into(),
|
|
)?;
|
|
|
|
border_wand.set_color("black")?;
|
|
let width = wand.get_image_width();
|
|
let border = width * 20 / 100;
|
|
wand.border_image(
|
|
&border_wand,
|
|
border,
|
|
border,
|
|
magick_rust::bindings::CompositeOperator_OverCompositeOp.into(),
|
|
)?;
|
|
|
|
let mut text_wand = DrawingWand::new();
|
|
let mut text_color_wand = PixelWand::new();
|
|
text_color_wand.set_color("white")?;
|
|
text_wand.set_fill_color(&text_color_wand);
|
|
text_wand.set_text_alignment(magick_rust::bindings::AlignType_CenterAlign);
|
|
text_wand.set_font("DejaVu-Serif")?;
|
|
|
|
if let Some(bottom_text) = &motivation.tagline {
|
|
let text_pos_x = wand.get_image_width() as f64 / 2.0;
|
|
let top_text_pos_y =
|
|
wand.get_image_height() as f64 - (wand.get_image_height() as f64 * 0.06);
|
|
let top_text_size = 0.08 * (wand.get_image_width() as f64);
|
|
text_wand.set_font_size(top_text_size);
|
|
wand.annotate_image(&text_wand, text_pos_x, top_text_pos_y, 0.0, &top_text)?;
|
|
|
|
let bot_text_pos_y =
|
|
wand.get_image_height() as f64 - (wand.get_image_height() as f64 * 0.03);
|
|
let bot_text_size = 0.03 * (wand.get_image_width() as f64);
|
|
text_wand.set_font_size(bot_text_size);
|
|
wand.annotate_image(&text_wand, text_pos_x, bot_text_pos_y, 0.0, bottom_text)?;
|
|
} else {
|
|
let font_size = 0.07 * (wand.get_image_width() as f64);
|
|
let text_pos_x = wand.get_image_width() as f64 / 2.0;
|
|
let text_pos_y = wand.get_image_height() as f64 - ((border / 2) as f64) + font_size * 0.33;
|
|
|
|
text_wand.set_font_size(font_size);
|
|
wand.annotate_image(&text_wand, text_pos_x, text_pos_y, 0.0, &top_text)?;
|
|
}
|
|
|
|
let img = wand.write_image_blob("jpeg")?;
|
|
|
|
let dur = std::time::Instant::now() - start_time;
|
|
info!("Generated motivation in {} seconds", dur.as_secs_f64());
|
|
Ok(img)
|
|
}
|