Skip to content

Commit

Permalink
allow resizing & reformatting of animated images
Browse files Browse the repository at this point in the history
  • Loading branch information
walterbm committed May 12, 2023
1 parent 3028929 commit 06b7313
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 9 deletions.
15 changes: 13 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rusty_resizer"
version = "0.1.9"
version = "0.4.0"
edition = "2021"

[lib]
Expand Down Expand Up @@ -30,5 +30,6 @@ url = "2.2.2"

[dev-dependencies]
actix-rt = "2.7.0"
reqwest = "0.11.10"
actix-service = "2.0.2"
gif = "0.12.0"
reqwest = "0.11.10"
13 changes: 8 additions & 5 deletions src/img/resizable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ impl ResizableImage {
};

if !(width == self.wand.get_image_width() && height == self.wand.get_image_height()) {
self.wand.thumbnail_image(width, height);
// if image has multiple frames use fit to resize the entire scene
if self.wand.get_image_scene() > 0 {
self.wand.fit(width, height);
} else {
self.wand.thumbnail_image(width, height);
}
}
}

Expand Down Expand Up @@ -58,17 +63,15 @@ impl ResizableImage {
.map_err(|_| ImageError::FailedWrite)?;

self.wand
.write_image_blob(format.extensions_str()[0])
.write_images_blob(format.extensions_str()[0])
.map_err(|_| ImageError::FailedWrite)
}

pub fn format(&self) -> Result<ImageFormat, ImageError> {
self.wand
.get_image_format()
.map_err(|_| ImageError::InvalidFormat)
.and_then(|format| {
ImageFormat::from_extension(&format).ok_or(ImageError::InvalidFormat)
})
.and_then(|format| ImageFormat::from_extension(format).ok_or(ImageError::InvalidFormat))
}

pub fn mime_type(self) -> Result<&'static str, ImageError> {
Expand Down
59 changes: 59 additions & 0 deletions tests/resize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,65 @@ async fn test_resize_can_resize_an_image() {
assert_eq!(height, 100, "height is equal to 100px");
}

#[actix_rt::test]
async fn test_resize_can_resize_an_animated_image() {
// Arrange
let address = spawn_app();
let client = reqwest::Client::new();
let test_image_one = "https://raw.githubusercontent.com/walterbm/rusty-resizer/main/tests/fixtures/test-image-animated.gif";

// Act
let response = client
.get(format!(
"{}/resize?source={}&width=100",
address, test_image_one
))
.send()
.await
.expect("Failed to execute request.");

// Assert
assert!(response.status().is_success());
assert_eq!(
response.headers().get("Content-Type").unwrap(),
"image/gif",
"content type is equal to image/gif"
);
assert_eq!(
response.headers().get("Cache-Control").unwrap(),
"max-age=3600",
"cache control max age is equal to 3600"
);
assert!(
response.headers().get("Vary").is_none(),
"response does not vary by request 'accept' header"
);

let bytes = response
.bytes()
.await
.expect("Failed to read response bytes");

let mut options = gif::DecodeOptions::new();
options.set_color_output(gif::ColorOutput::RGBA);

let mut gif_decoder = options
.read_info(Cursor::new(bytes))
.expect("Failed to decode animated image");

let mut frame_counter = 0;
while let Some(frame) = gif_decoder
.read_next_frame()
.expect("Failed to decode image frame")
{
frame_counter += 1;
assert_eq!(frame.width, 99, "width is equal to 99px");
assert_eq!(frame.height, 57, "height is equal to 57px");
}

assert_eq!(frame_counter, 55, "resized animated image has 55 frames");
}

#[actix_rt::test]
async fn test_resize_can_resize_an_image_with_only_one_dimension_and_preserve_aspect_ratio() {
// Arrange
Expand Down

0 comments on commit 06b7313

Please sign in to comment.