mirror of
https://github.com/chatmail/core.git
synced 2026-07-22 10:53:34 +03:00
Compare commits
6 Commits
v2.56.0
...
iequidoo/m
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
417349197c | ||
|
|
a25304604a | ||
|
|
52e4e42373 | ||
|
|
18ed89abd5 | ||
|
|
89a281dd27 | ||
|
|
456891a0af |
37
src/blob.rs
37
src/blob.rs
@@ -389,14 +389,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;
|
||||
@@ -435,6 +430,32 @@ 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 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_wh
|
||||
};
|
||||
|
||||
if target_wh > n_px_longest_side
|
||||
|| !is_avatar && target_wh > (f64::from(n_px_longest_side) * 0.98) as u32
|
||||
{
|
||||
target_wh = n_px_longest_side;
|
||||
};
|
||||
|
||||
loop {
|
||||
if mem::take(&mut add_white_bg) {
|
||||
self::add_white_bg(&mut img);
|
||||
@@ -468,7 +489,7 @@ impl<'a> BlobObject<'a> {
|
||||
));
|
||||
}
|
||||
|
||||
target_wh = target_wh * 2 / 3;
|
||||
target_wh = target_wh * 7 / 8;
|
||||
} else {
|
||||
info!(
|
||||
context,
|
||||
|
||||
@@ -258,6 +258,26 @@ async fn test_selfavatar_copy_without_recode() {
|
||||
assert_eq!(avatar_cfg, avatar_blob.to_str().map(|s| s.to_string()));
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_recode_image_long_narrow() {
|
||||
let bytes = include_bytes!("../../test-data/image/screenshot.png");
|
||||
SendImageCheckMediaquality {
|
||||
viewtype: Viewtype::Image,
|
||||
media_quality_config: "0",
|
||||
bytes,
|
||||
extension: "jpg",
|
||||
original_width: 1920,
|
||||
original_height: 1080,
|
||||
compressed_width: 1872,
|
||||
compressed_height: 1053,
|
||||
..Default::default()
|
||||
}
|
||||
.test()
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(false);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_recode_image_1() {
|
||||
let bytes = include_bytes!("../../test-data/image/avatar1000x1000.jpg");
|
||||
@@ -384,8 +404,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 +495,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 +515,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()
|
||||
|
||||
@@ -193,17 +193,17 @@ pub const DC_LP_AUTH_NORMAL: i32 = 0x4;
|
||||
pub const DC_LP_AUTH_FLAGS: i32 = DC_LP_AUTH_OAUTH2 | DC_LP_AUTH_NORMAL;
|
||||
|
||||
// max. weight of images to send w/o recoding
|
||||
pub const BALANCED_IMAGE_BYTES: usize = 500_000;
|
||||
pub const BALANCED_IMAGE_BYTES: usize = 1;
|
||||
pub const WORSE_IMAGE_BYTES: usize = 130_000;
|
||||
|
||||
// max. width/height and bytes of an avatar
|
||||
pub(crate) const BALANCED_AVATAR_SIZE: u32 = 512;
|
||||
pub(crate) const BALANCED_AVATAR_BYTES: usize = 60_000;
|
||||
pub(crate) const WORSE_AVATAR_SIZE: u32 = 128;
|
||||
pub(crate) const WORSE_AVATAR_SIZE: u32 = 256;
|
||||
pub(crate) const WORSE_AVATAR_BYTES: usize = 20_000; // this also fits to Outlook servers don't allowing headers larger than 32k.
|
||||
|
||||
// max. width/height of images scaled down because of being too huge
|
||||
pub const BALANCED_IMAGE_SIZE: u32 = 1280;
|
||||
pub const BALANCED_IMAGE_SIZE: u32 = 1408;
|
||||
pub const WORSE_IMAGE_SIZE: u32 = 640;
|
||||
|
||||
/// Limit for received images size. Bigger images become `Viewtype::File` to avoid excessive memory
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user