mirror of
https://git.asonix.dog/asonix/pict-rs
synced 2024-12-22 19:31:35 +00:00
Expose cropping
This commit is contained in:
parent
6d3078f438
commit
a750364e27
4 changed files with 84 additions and 2 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1449,7 +1449,7 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pict-rs"
|
name = "pict-rs"
|
||||||
version = "0.3.0-alpha.1"
|
version = "0.3.0-alpha.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-form-data",
|
"actix-form-data",
|
||||||
"actix-fs",
|
"actix-fs",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "pict-rs"
|
name = "pict-rs"
|
||||||
description = "A simple image hosting service"
|
description = "A simple image hosting service"
|
||||||
version = "0.3.0-alpha.1"
|
version = "0.3.0-alpha.2"
|
||||||
authors = ["asonix <asonix@asonix.dog>"]
|
authors = ["asonix <asonix@asonix.dog>"]
|
||||||
license = "AGPL-3.0"
|
license = "AGPL-3.0"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
|
@ -128,6 +128,11 @@ pict-rs offers the following endpoints:
|
||||||
square using raw pixel sampling
|
square using raw pixel sampling
|
||||||
- `resize={int}`: produce a thumbnail of the image fitting inside an `{int}` by `{int}` square
|
- `resize={int}`: produce a thumbnail of the image fitting inside an `{int}` by `{int}` square
|
||||||
using a Lanczos2 filter. This is slower than sampling but looks a bit better in some cases
|
using a Lanczos2 filter. This is slower than sampling but looks a bit better in some cases
|
||||||
|
- `crop={int-w}x{int-h}`: produce a cropped version of the image with an `{int-w}` by `{int-h}`
|
||||||
|
aspect ratio. The resulting crop will be centered on the image. Either the width or height
|
||||||
|
of the image will remain full-size, depending on the image's aspect ratio and the requested
|
||||||
|
aspect ratio. For example, a 1600x900 image cropped with a 1x1 aspect ratio will become 900x900. A
|
||||||
|
1600x1100 image cropped with a 16x9 aspect ratio will become 1600x900.
|
||||||
|
|
||||||
Supported `ext` file extensions include `png`, `jpg`, and `webp`
|
Supported `ext` file extensions include `png`, `jpg`, and `webp`
|
||||||
|
|
||||||
|
|
|
@ -170,6 +170,82 @@ impl Processor for Resize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) struct Crop(usize, usize);
|
||||||
|
|
||||||
|
impl Processor for Crop {
|
||||||
|
fn name() -> &'static str
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
"crop"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_processor(s: &str) -> bool {
|
||||||
|
s == Self::name()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(_: &str, v: &str) -> Option<Box<dyn Processor + Send>> {
|
||||||
|
let mut iter = v.split('x');
|
||||||
|
let first = iter.next()?;
|
||||||
|
let second = iter.next()?;
|
||||||
|
|
||||||
|
let width = first.parse::<usize>().ok()?;
|
||||||
|
let height = second.parse::<usize>().ok()?;
|
||||||
|
|
||||||
|
if width == 0 || height == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if width > 20 || height > 20 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(Box::new(Crop(width, height)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path(&self, mut path: PathBuf) -> PathBuf {
|
||||||
|
path.push(Self::name());
|
||||||
|
path.push(format!("{}x{}", self.0, self.1));
|
||||||
|
path
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process(&self, wand: &mut MagickWand) -> Result<(), UploadError> {
|
||||||
|
let width = wand.get_image_width();
|
||||||
|
let height = wand.get_image_height();
|
||||||
|
|
||||||
|
// 16x9 becomes 16/9, which is bigger than 16/10. a bigger number means a wider image
|
||||||
|
//
|
||||||
|
// Crop ratios bigger than Image ratios mean cropping the image's height and leaving the
|
||||||
|
// width alone.
|
||||||
|
let img_ratio = width as f64 / height as f64;
|
||||||
|
let crop_ratio = self.0 as f64 / self.1 as f64;
|
||||||
|
|
||||||
|
let final_width;
|
||||||
|
let final_height;
|
||||||
|
|
||||||
|
let x_offset;
|
||||||
|
let y_offset;
|
||||||
|
|
||||||
|
if crop_ratio > img_ratio {
|
||||||
|
final_height = (width as f64 / self.0 as f64 * self.1 as f64) as usize;
|
||||||
|
final_width = width;
|
||||||
|
|
||||||
|
x_offset = 0;
|
||||||
|
y_offset = ((height - final_height) as f64 / 2.0) as isize;
|
||||||
|
} else {
|
||||||
|
final_height = height;
|
||||||
|
final_width = (height as f64 / self.1 as f64 * self.0 as f64) as usize;
|
||||||
|
|
||||||
|
x_offset = ((width - final_width) as f64 / 2.0) as isize;
|
||||||
|
y_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wand.op(|w| w.crop_image(final_width, final_height, x_offset, y_offset))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct Blur(f64);
|
pub(crate) struct Blur(f64);
|
||||||
|
|
||||||
impl Processor for Blur {
|
impl Processor for Blur {
|
||||||
|
@ -236,6 +312,7 @@ pub(crate) fn build_chain(args: &[(String, String)]) -> ProcessChain {
|
||||||
parse!(Identity, k, v);
|
parse!(Identity, k, v);
|
||||||
parse!(Thumbnail, k, v);
|
parse!(Thumbnail, k, v);
|
||||||
parse!(Resize, k, v);
|
parse!(Resize, k, v);
|
||||||
|
parse!(Crop, k, v);
|
||||||
parse!(Blur, k, v);
|
parse!(Blur, k, v);
|
||||||
|
|
||||||
debug!("Skipping {}: {}, invalid", k, v);
|
debug!("Skipping {}: {}, invalid", k, v);
|
||||||
|
|
Loading…
Reference in a new issue