Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 32 additions & 8 deletions src/blob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use futures::StreamExt;
use image::ImageReader;
use image::codecs::jpeg::JpegEncoder;
use image::{DynamicImage, GenericImage, GenericImageView, ImageFormat, Pixel, Rgba};
use num_traits::FromPrimitive;
use num_traits::{FromPrimitive, cast};
use tokio::{fs, task};
use tokio_stream::wrappers::ReadDirStream;

Expand Down Expand Up @@ -388,14 +388,9 @@ impl<'a> BlobObject<'a> {
_ => img,
};

// max_wh is the maximum image width and height, i.e. the resolution-limit.
// target_wh target-resolution for resizing the image.
// max_wh is the maximum image width and height, i.e. the resolution-limit,
// as set by `Config::MediaQuality`.
let exceeds_wh = img.width() > max_wh || img.height() > max_wh;
let mut target_wh = if exceeds_wh {
max_wh
} else {
max(img.width(), img.height())
};
let exceeds_max_bytes = nr_bytes > max_bytes as u64;

let jpeg_quality = 75;
Expand Down Expand Up @@ -434,6 +429,35 @@ impl<'a> BlobObject<'a> {
});

if do_scale {
let n_px_longest_side = max(img.width(), img.height());

// target_wh will be used as the target-resolution for resizing the image,
// so that the longest sides of the image match the target-resolution.
let mut target_wh = if !is_avatar {
let n_all_px_sqrt = f64::from(img.width() * img.height()).sqrt();
// Limit resolution to the number of pixels that fit within max_wh * max_wh,
// so that the image-quality does not depend on the aspect-ratio.
let limit: Option<u32> = cast(
(f64::from(n_px_longest_side) * (f64::from(max_wh) / n_all_px_sqrt))
.floor(),
);
let mut resolution_limit = limit.context("resolution_limit is out of range")?;
// Align at least one dimension of the resampled image to a multiple of 8 pixels,
// to have fewer partially used JPEG-blocks (which represent 8x8 pixels each).
if resolution_limit < n_px_longest_side {
while !resolution_limit.is_multiple_of(8) {
resolution_limit -= 1
}
}
resolution_limit
} else {
max_wh
};

if target_wh > n_px_longest_side {
target_wh = n_px_longest_side;
};

loop {
if mem::take(&mut add_white_bg) {
self::add_white_bg(&mut img);
Expand Down
12 changes: 6 additions & 6 deletions src/blob/blob_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,8 @@ async fn test_recode_image_balanced_png() {
extension: "png",
original_width: 1920,
original_height: 1080,
compressed_width: constants::WORSE_IMAGE_SIZE,
compressed_height: constants::WORSE_IMAGE_SIZE * 1080 / 1920,
compressed_width: 848,
compressed_height: 477,
..Default::default()
}
.test()
Expand Down Expand Up @@ -475,8 +475,8 @@ async fn test_recode_image_rgba_png_to_jpeg() {
extension: "png",
original_width: 1920,
original_height: 1080,
compressed_width: constants::WORSE_IMAGE_SIZE,
compressed_height: constants::WORSE_IMAGE_SIZE * 1080 / 1920,
compressed_width: 848,
compressed_height: 477,
..Default::default()
}
.test()
Expand All @@ -495,8 +495,8 @@ async fn test_recode_image_huge_jpg() {
has_exif: true,
original_width: 1920,
original_height: 1080,
compressed_width: constants::BALANCED_IMAGE_SIZE,
compressed_height: constants::BALANCED_IMAGE_SIZE * 1080 / 1920,
compressed_width: 1704,
compressed_height: 959,
..Default::default()
}
.test()
Expand Down
2 changes: 1 addition & 1 deletion src/tests/pre_messages/additional_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ async fn test_additional_text_on_different_viewtypes() -> Result<()> {
let (pre_message, _, _) = send_large_image_message(alice, a_group_id).await?;
let msg = bob.recv_msg(&pre_message).await;
assert_eq!(msg.text, "test".to_owned());
assert_eq!(msg.get_text(), "test [Image – 146.12 KiB]".to_owned());
assert_eq!(msg.get_text(), "test [Image – 228.45 KiB]".to_owned());

Ok(())
}
6 changes: 3 additions & 3 deletions src/tests/pre_messages/receiving.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,9 @@ async fn test_receive_pre_message_image() -> Result<()> {
// test that metadata is correctly returned by methods
assert_eq!(msg.get_post_message_viewtype(), Some(Viewtype::Image));
// recoded image dimensions
assert_eq!(msg.get_filebytes(bob).await?, Some(149632));
assert_eq!(msg.get_height(), 1280);
assert_eq!(msg.get_width(), 720);
assert_eq!(msg.get_filebytes(bob).await?, Some(233935));
assert_eq!(msg.get_height(), 1704);
assert_eq!(msg.get_width(), 959);

Ok(())
}
Expand Down
Loading