Random placement of fg image and some scaling improvements

This commit is contained in:
Joey Hines 2025-04-18 15:12:22 -06:00
parent d71b4bd986
commit cda4339386
Signed by: joeyahines
GPG Key ID: 38BA6F25C94C9382
3 changed files with 46 additions and 12 deletions

2
Cargo.lock generated
View File

@ -1080,7 +1080,7 @@ dependencies = [
[[package]]
name = "fren"
version = "1.3.0"
version = "1.3.1"
dependencies = [
"axum 0.8.1",
"base64 0.22.1",

View File

@ -1,6 +1,6 @@
[package]
name = "fren"
version = "1.3.0"
version = "1.3.1"
edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@ -4,12 +4,43 @@ use crate::error::Error;
use crate::models::motivation::{Motivation, MotivationConfig};
use magick_rust::{CompositeOperator, DrawingWand, FilterType, MagickWand, PixelWand};
use poise::serenity_prelude::builder::{CreateAttachment, CreateMessage};
use rand::Rng;
use rand::distr::{Distribution, StandardUniform};
use reqwest::{Client, Url};
use serde::Deserialize;
use std::borrow::Cow;
#[derive(Debug, Deserialize)]
pub enum Alignment {
Left,
Center,
Right,
}
impl Alignment {
pub fn offset(&self) -> f64 {
match self {
Alignment::Left => 0.25,
Alignment::Center => 0.5,
Alignment::Right => 0.75,
}
}
}
impl Distribution<Alignment> for StandardUniform {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Alignment {
match rng.random_range(0..=2) {
0 => Alignment::Left,
1 => Alignment::Center,
_ => Alignment::Right,
}
}
}
pub async fn create_greenscreen_image(
background_image_url: Url,
foreground_image_url: Url,
alignment: Alignment,
) -> Result<Vec<u8>, Error> {
let client = Client::new();
@ -41,6 +72,8 @@ pub async fn create_greenscreen_image(
let foreground_height = foreground_wand.get_image_height();
let foreground_width = foreground_wand.get_image_width();
let ratio = foreground_height as f64 / foreground_width as f64;
let (scale_height, scale_width) =
if foreground_height > background_height && foreground_width > background_width {
(
@ -50,22 +83,19 @@ pub async fn create_greenscreen_image(
} else if foreground_height > background_height {
let scale = background_height as f64 / foreground_height as f64;
(scale, scale)
(scale, scale * ratio)
} else if foreground_width > background_width {
let scale = background_width as f64 / foreground_width as f64;
(scale, scale)
(scale * ratio, scale)
} else {
(1.0, 1.0)
};
foreground_wand.scale_image(
scale_width * 0.75,
scale_height * 0.75,
FilterType::Lanczos2,
)?;
foreground_wand.scale_image(scale_width * 0.6, scale_height * 0.6, FilterType::Lanczos2)?;
let pos_x = background_width / 2 - foreground_wand.get_image_width() / 2;
let pos_x = background_width as f64 * alignment.offset()
- foreground_wand.get_image_width() as f64 / 2.0;
let pos_y = background_height - foreground_wand.get_image_height();
background_wand.compose_images(
&foreground_wand,
@ -75,7 +105,7 @@ pub async fn create_greenscreen_image(
pos_y as isize,
)?;
Ok(background_wand.write_image_blob("jpg")?)
Ok(background_wand.write_image_blob("png")?)
}
pub async fn create_motivation_image(motivation: Motivation) -> Result<Vec<u8>, Error> {
@ -194,7 +224,11 @@ pub async fn green_screen(
.cloned()
.unwrap();
let image = create_greenscreen_image(background.link.clone(), foreground.link.clone()).await?;
let alignment: Alignment = rand::random();
let image =
create_greenscreen_image(background.link.clone(), foreground.link.clone(), alignment)
.await?;
ctx.channel_id()
.send_message(