This commit is contained in:
Timofey Gelazoniya 2023-10-17 21:07:46 +03:00
parent d9d416a0fe
commit e0de5360dd
Signed by: zeldon
GPG Key ID: 047886915281DD2A
2 changed files with 79 additions and 50 deletions

View File

@ -1,59 +1,26 @@
#![deny(clippy::all)]
#![allow(dead_code)]
use magick_rust::{magick_wand_genesis, MagickWand};
use liquid_rescale_task::LiquidRescaleTask;
use napi::{
bindgen_prelude::{AsyncTask, Buffer},
Task,
bindgen_prelude::{AbortSignal, AsyncTask, Buffer},
Result,
};
use napi_derive::napi;
use std::sync::Once;
static START: Once = Once::new();
struct LiquidRescale {
input: Buffer,
}
mod liquid_rescale_task;
#[napi]
impl Task for LiquidRescale {
type Output = Buffer;
type JsValue = Buffer;
fn compute(&mut self) -> napi::Result<Self::Output> {
let buffer: Vec<u8> = self.input.clone().into();
let result = lib_liquid_rescale(&buffer, 200, 400).unwrap();
Ok(result.into())
}
fn resolve(&mut self, _env: napi::Env, output: Self::Output) -> napi::Result<Self::JsValue> {
Ok(output)
}
}
#[napi(js_name = "liquidRescaleImage")]
fn liquid_rescale(input_image: Buffer) -> AsyncTask<LiquidRescale> {
AsyncTask::new(LiquidRescale { input: input_image })
}
fn lib_liquid_rescale(input_image: &[u8], width: usize, height: usize) -> Result<Vec<u8>, String> {
START.call_once(|| {
magick_wand_genesis();
});
let wand = MagickWand::new();
if let Err(err) = wand.read_image_blob(input_image) {
return Err(format!("Failed to read image: {}", err));
}
if let Err(err) = wand.liquid_rescale_image(width, height, 1.0, 0.0) {
return Err(format!("Failed to perform liquid rescaling: {}", err));
}
let output_image = match wand.write_image_blob("JPEG") {
Ok(image) => image,
Err(err) => return Err(format!("Failed to write image: {}", err)),
};
Ok(output_image)
pub fn liquid_rescale(
input_image: Buffer,
output_width: Option<u32>,
output_height: Option<u32>,
signal: Option<AbortSignal>,
) -> Result<AsyncTask<LiquidRescaleTask>> {
let task = LiquidRescaleTask::new(
input_image,
output_width.unwrap_or(200) as usize,
output_height.unwrap_or(400) as usize,
);
Ok(AsyncTask::with_optional_signal(task, signal))
}

View File

@ -0,0 +1,62 @@
use std::sync::Once;
use magick_rust::{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}")))?;
wand.liquid_rescale_image(width, height, 0.0, 1.0)
.map_err(|err| Error::new(Status::GenericFailure, format!("{err}")))?;
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)
}
}