mirror of
https://github.com/chatmail/core.git
synced 2026-05-09 01:46:30 +03:00
feat: Make quality of images sent in chats more consistent
Currently, the resolution of a resized image that was sent in a chat, depends on the aspect-ratio. Assuming the `balanced`-quality-setting is used, a square image, that is larger than the limits for resolution and file-size, will be resized to 1280x1280 (1,638,400 pixels), an image with an aspect-ratio of 16:9, will be resized to 1280x720 (921,600 pixels), and if the aspect-ratio is 32:9, to 1280x360 (460,800 pixels). This change makes it so, that the number of pixels, in images with different aspect-ratios, will be similar.
This commit is contained in:
22
src/blob.rs
22
src/blob.rs
@@ -430,12 +430,28 @@ impl<'a> BlobObject<'a> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if do_scale {
|
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,
|
// 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.
|
// so that the longest sides of the image match the target-resolution.
|
||||||
let mut target_wh = if exceeds_wh {
|
let mut target_wh = if !is_avatar {
|
||||||
max_wh
|
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 {
|
} else {
|
||||||
max(img.width(), img.height())
|
max_wh
|
||||||
|
};
|
||||||
|
|
||||||
|
if target_wh > n_px_longest_side {
|
||||||
|
target_wh = n_px_longest_side;
|
||||||
};
|
};
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
|||||||
@@ -384,8 +384,8 @@ async fn test_recode_image_balanced_png() {
|
|||||||
extension: "png",
|
extension: "png",
|
||||||
original_width: 1920,
|
original_width: 1920,
|
||||||
original_height: 1080,
|
original_height: 1080,
|
||||||
compressed_width: constants::WORSE_IMAGE_SIZE,
|
compressed_width: 848,
|
||||||
compressed_height: constants::WORSE_IMAGE_SIZE * 1080 / 1920,
|
compressed_height: 477,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.test()
|
.test()
|
||||||
@@ -475,8 +475,8 @@ async fn test_recode_image_rgba_png_to_jpeg() {
|
|||||||
extension: "png",
|
extension: "png",
|
||||||
original_width: 1920,
|
original_width: 1920,
|
||||||
original_height: 1080,
|
original_height: 1080,
|
||||||
compressed_width: constants::WORSE_IMAGE_SIZE,
|
compressed_width: 848,
|
||||||
compressed_height: constants::WORSE_IMAGE_SIZE * 1080 / 1920,
|
compressed_height: 477,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.test()
|
.test()
|
||||||
@@ -495,8 +495,8 @@ async fn test_recode_image_huge_jpg() {
|
|||||||
has_exif: true,
|
has_exif: true,
|
||||||
original_width: 1920,
|
original_width: 1920,
|
||||||
original_height: 1080,
|
original_height: 1080,
|
||||||
compressed_width: constants::BALANCED_IMAGE_SIZE,
|
compressed_width: 1704,
|
||||||
compressed_height: constants::BALANCED_IMAGE_SIZE * 1080 / 1920,
|
compressed_height: 959,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.test()
|
.test()
|
||||||
|
|||||||
@@ -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 (pre_message, _, _) = send_large_image_message(alice, a_group_id).await?;
|
||||||
let msg = bob.recv_msg(&pre_message).await;
|
let msg = bob.recv_msg(&pre_message).await;
|
||||||
assert_eq!(msg.text, "test".to_owned());
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -393,9 +393,9 @@ async fn test_receive_pre_message_image() -> Result<()> {
|
|||||||
// test that metadata is correctly returned by methods
|
// test that metadata is correctly returned by methods
|
||||||
assert_eq!(msg.get_post_message_viewtype(), Some(Viewtype::Image));
|
assert_eq!(msg.get_post_message_viewtype(), Some(Viewtype::Image));
|
||||||
// recoded image dimensions
|
// recoded image dimensions
|
||||||
assert_eq!(msg.get_filebytes(bob).await?, Some(149632));
|
assert_eq!(msg.get_filebytes(bob).await?, Some(233935));
|
||||||
assert_eq!(msg.get_height(), 1280);
|
assert_eq!(msg.get_height(), 1704);
|
||||||
assert_eq!(msg.get_width(), 720);
|
assert_eq!(msg.get_width(), 959);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user