libdistbot/src/liquid_rescale_task.rs

66 lines
1.9 KiB
Rust

use std::sync::Once;
use magick_rust::{bindings::FilterType_LanczosFilter, magick_wand_genesis, MagickWand};
use napi::{bindgen_prelude::Buffer, Error, Result, Status, Task};
static START: Once = Once::new();
pub struct LiquidRescaleTask {
input_image: Buffer,
output_width: usize,
output_height: usize,
}
impl LiquidRescaleTask {
#[inline]
pub fn new(
input_image: Buffer,
output_width: usize,
output_height: usize,
) -> LiquidRescaleTask {
LiquidRescaleTask {
input_image,
output_width,
output_height,
}
}
#[inline]
pub fn liquid_rescale(input_image: Vec<u8>, width: usize, height: usize) -> Result<Buffer> {
START.call_once(|| {
magick_wand_genesis();
});
let wand = MagickWand::new();
wand.read_image_blob(input_image)
.map_err(|err| Error::new(Status::InvalidArg, format!("{err}")))?;
let input_width = wand.get_image_width();
let input_height = wand.get_image_height();
wand.liquid_rescale_image(width, height, 1.0, 0.0)
.map_err(|err| Error::new(Status::GenericFailure, format!("{err}")))?;
wand.resize_image(input_width, input_height, FilterType_LanczosFilter);
let output_image = wand
.write_image_blob("JPEG")
.map_err(|err| Error::new(Status::GenericFailure, format!("{err}")))?;
Ok(output_image.into())
}
}
impl Task for LiquidRescaleTask {
type Output = Buffer;
type JsValue = Buffer;
fn compute(&mut self) -> Result<Self::Output> {
Self::liquid_rescale(
self.input_image.clone().into(),
self.output_width,
self.output_height,
)
}
fn resolve(&mut self, _env: napi::Env, output: Self::Output) -> Result<Self::JsValue> {
Ok(output)
}
}