#![warn(clippy::pedantic)]
#![warn(clippy::nursery)]
mod body;
mod subbody;
mod title;
mod utils;
mod via;
use image::{imageops, DynamicImage, Rgba, RgbaImage};
const BLACK: Rgba<u8> = Rgba([0, 0, 0, 255]);
const TRANSPARENT: Rgba<u8> = Rgba([0, 0, 0, 0]);
#[must_use]
pub fn generate_graphic(
title: &str,
body: Option<&str>,
subbody: Option<&str>,
via: Option<&str>,
image: &DynamicImage,
) -> DynamicImage {
let title = title.trim().to_uppercase();
let body = body.map(|body| body.trim().to_uppercase());
let subbody = subbody.map(|subbody| subbody.trim().to_uppercase());
let via = via.map(|via| via.trim().to_uppercase());
let mut img = background(image);
title::draw(&mut img, &title);
if let Some(body) = &body {
body::draw(&mut img, body);
}
if let Some(subbody) = &subbody {
subbody::draw(&mut img, subbody);
}
if let Some(via) = &via {
via::draw(&mut img, via);
}
img
}
fn background(img: &DynamicImage) -> DynamicImage {
let photo = {
let (img_width, img_height) = (img.width(), img.height());
let aspect_ratio = 3.0 / 2.0;
let (width, height) = if f64::from(img_width) > f64::from(img_height) * aspect_ratio {
(img_height * 3 / 2, img_height)
} else {
(img_width, img_width / 3 * 2)
};
let x = (img_width - width) / 2;
let y = (img_height - height) / 2;
img.crop_imm(x, y, width, height)
};
let mut img =
DynamicImage::ImageRgba8(RgbaImage::from_pixel(photo.width(), photo.width(), BLACK));
imageops::overlay(&mut img, &photo, 0, 0);
let mut img = img.thumbnail_exact(1024, 1024);
let side_length = img.height();
let overlay_height = utils::div_ceil(side_length, 3);
let gradient = {
let mut gradient = RgbaImage::new(side_length, overlay_height);
imageops::vertical_gradient(&mut gradient, &TRANSPARENT, &BLACK);
gradient
};
imageops::overlay(&mut img, &gradient, 0, overlay_height.into());
img
}