use std::path::PathBuf;
use std::process::Command;
use anyhow::Context;
use rayon::prelude::*;
use tempfile::TempDir;
use crate::utils::IMG_EXT;
use crate::Result;
pub fn apply_shadow_effect(time_codes: &[u128], tempdir: &TempDir, bg_color: String) {
apply_effect(
time_codes,
tempdir,
Box::new(move |file| {
let e = Command::new("convert")
.arg(file.to_str().unwrap())
.arg("(")
.args(["+clone", "-background", "black", "-shadow", "100x20+0+0"])
.arg(")")
.args(["+swap", "-background", bg_color.as_str()])
.args(["-layers", "merge"])
.arg(file.to_str().unwrap())
.output()
.context("Cannot apply shadow decor effect")?;
if !e.status.success() {
anyhow::bail!("{}", String::from_utf8_lossy(&e.stderr))
} else {
Ok(())
}
}),
)
}
pub fn apply_big_sur_corner_effect(time_codes: &[u128], tempdir: &TempDir) {
let radius = 13;
apply_effect(
time_codes,
tempdir,
Box::new(move |file| {
let e = Command::new("convert")
.arg(file.to_str().unwrap())
.arg("(")
.args(["+clone", "-alpha", "extract"])
.args([
"-draw",
&format!(
"fill black polygon 0,0 0,{r} {r},0 fill white circle {r},{r} {r},0",
r = radius
),
])
.args(["(", "+clone", "-flip", ")"])
.args(["-compose", "Multiply", "-composite"])
.args(["(", "+clone", "-flop", ")"])
.args(["-compose", "Multiply", "-composite"])
.arg(")")
.args(["-alpha", "off", "-compose", "CopyOpacity", "-composite"])
.arg(file.to_str().unwrap())
.output()
.context("Cannot apply corner decor effect")?;
if !e.status.success() {
anyhow::bail!("{}", String::from_utf8_lossy(&e.stderr))
} else {
Ok(())
}
}),
)
}
fn apply_effect(
time_codes: &[u128],
tempdir: &TempDir,
effect: Box<dyn Fn(PathBuf) -> Result<()> + Send + Sync>,
) {
time_codes.into_par_iter().for_each(|tc| {
let file = tempdir
.path()
.join(crate::utils::file_name_for(tc, IMG_EXT));
if let Err(e) = effect(file) {
eprintln!("{}", e);
}
});
}