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, ) -> Result, 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) }