diff --git a/src/blob.rs b/src/blob.rs index 4c69299d6..ee9a4bbe9 100644 --- a/src/blob.rs +++ b/src/blob.rs @@ -430,12 +430,28 @@ 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 exceeds_wh { - max_wh + 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 mut resolution_limit = + (f64::from(n_px_longest_side) * (f64::from(max_wh) / n_all_px_sqrt)) as u32; + // Align (at least) two sides of the resampled image to a multiple of 8 pixels, + // to have fewer partially used JPEG-blocks (which represent 8x8 pixels each). + while !resolution_limit.is_multiple_of(8) { + resolution_limit -= 1 + } + resolution_limit } else { - max(img.width(), img.height()) + max_wh + }; + + if target_wh > n_px_longest_side { + target_wh = n_px_longest_side; }; loop { diff --git a/src/blob/blob_tests.rs b/src/blob/blob_tests.rs index ed5a2b001..63763f54a 100644 --- a/src/blob/blob_tests.rs +++ b/src/blob/blob_tests.rs @@ -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() @@ -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() @@ -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() diff --git a/src/tests/pre_messages/additional_text.rs b/src/tests/pre_messages/additional_text.rs index 0af33ec8c..f37baa4e4 100644 --- a/src/tests/pre_messages/additional_text.rs +++ b/src/tests/pre_messages/additional_text.rs @@ -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(()) } diff --git a/src/tests/pre_messages/receiving.rs b/src/tests/pre_messages/receiving.rs index 1926bbd07..25c599f77 100644 --- a/src/tests/pre_messages/receiving.rs +++ b/src/tests/pre_messages/receiving.rs @@ -393,9 +393,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(()) }