mirror of
https://github.com/chatmail/core.git
synced 2026-09-22 13:01:21 +03:00
feat: better quality of image recoding (#8682)
this PR introduces a better quality of image recoding, consuming max. 900k instead of 500k (average is much less). the PR roughly doubles the number of pixels sent in an image. the old 1280px were set 8 years ago, data and storage has improved since then, so it is reasonable to double the number if pixels used for sending an image. this will be a quality boost for many images, while not resulting in a doubled size for all of them; many images will only be a little larger in bytes, see test. we could always go higher, of course, but it comes at costs of relay storage and data, so we stay conservative, even in that increase. the "worse quality" setting is not adapted on purpose, there we really stay at the end of what is bearable :) cc @adbenitez --------- Co-authored-by: l <link2xt@testrun.org>
This commit is contained in:
@@ -386,7 +386,7 @@ impl<'a> BlobObject<'a> {
|
||||
let exceeds_wh = img.width() > max_wh || img.height() > max_wh;
|
||||
let exceeds_max_bytes = nr_bytes > max_bytes as u64;
|
||||
|
||||
let jpeg_quality = 75;
|
||||
let jpeg_quality = 75; // 70-80 is the sweet spot of quality vs. bytes/pixel. if one wants to spend more bytes in quality, better increase resolution
|
||||
let ofmt = match fmt {
|
||||
ImageFormat::Png if !exceeds_max_bytes => ImageOutputFormat::Png,
|
||||
ImageFormat::Jpeg => {
|
||||
|
||||
@@ -508,17 +508,17 @@ async fn test_recode_image_rgba_png_to_jpeg() {
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_recode_image_huge_jpg() {
|
||||
let bytes = include_bytes!("../../test-data/image/screenshot.jpg");
|
||||
let bytes = include_bytes!("../../test-data/image/screenshot-2560x1440.jpg");
|
||||
SendImageCheckMediaquality {
|
||||
viewtype: Viewtype::Image,
|
||||
media_quality_config: "0",
|
||||
bytes,
|
||||
extension: "jpg",
|
||||
has_exif: true,
|
||||
original_width: 1920,
|
||||
original_height: 1080,
|
||||
compressed_width: 1704,
|
||||
compressed_height: 959,
|
||||
original_width: 2560,
|
||||
original_height: 1440,
|
||||
compressed_width: 2344,
|
||||
compressed_height: 1319,
|
||||
..Default::default()
|
||||
}
|
||||
.test()
|
||||
|
||||
@@ -148,8 +148,9 @@ pub const DC_DESIRED_TEXT_LINE_LEN: usize = 100;
|
||||
/// `char`s), not Unicode Grapheme Clusters.
|
||||
pub const DC_DESIRED_TEXT_LEN: usize = DC_DESIRED_TEXT_LINE_LEN * DC_DESIRED_TEXT_LINES;
|
||||
|
||||
// max. weight of images to send w/o recoding
|
||||
pub const BALANCED_IMAGE_BYTES: usize = 500_000;
|
||||
/// max. weight of images to send w/o recoding.
|
||||
// this is an estimation to the size we get when recoding high detail images.
|
||||
pub const BALANCED_IMAGE_BYTES: usize = 940_000;
|
||||
pub const WORSE_IMAGE_BYTES: usize = 130_000;
|
||||
|
||||
// max. width/height and bytes of an avatar
|
||||
@@ -159,7 +160,7 @@ 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 = 1760;
|
||||
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 – 228.45 KiB]".to_owned());
|
||||
assert_eq!(msg.get_text(), "test [Image – 275.46 KiB]".to_owned());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -501,9 +501,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(233935));
|
||||
assert_eq!(msg.get_height(), 1704);
|
||||
assert_eq!(msg.get_width(), 959);
|
||||
assert_eq!(msg.get_filebytes(bob).await?, Some(282068));
|
||||
assert_eq!(msg.get_height(), 1920);
|
||||
assert_eq!(msg.get_width(), 1080);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user