mirror of
https://github.com/chatmail/core.git
synced 2026-04-25 09:26:30 +03:00
feat: Don't scale down huge non-JPEGs, recode them first (#7977)
If after recoding to JPEG an image isn't huge anymore, don't scale it down, this preserves quality of most screenshots. For JPEGs however we don't try to recode them w/o scaling down: - They are already JPEG-encoded, maybe with higher quality, but anyway. - We don't want extra CPU work for most photos.
This commit is contained in:
14
src/blob.rs
14
src/blob.rs
@@ -416,6 +416,17 @@ impl<'a> BlobObject<'a> {
|
||||
// also `Viewtype::Gif` (maybe renamed to `Animation`) should be used for animated
|
||||
// images.
|
||||
let do_scale = exceeds_max_bytes
|
||||
// Don't recode huge JPEGs w/o resizing:
|
||||
// - It may be huge because of high JPEG quality, but we don't know that.
|
||||
// - We don't want extra CPU work for most photos.
|
||||
&& (fmt == ImageFormat::Jpeg
|
||||
|| encoded_img_exceeds_bytes(
|
||||
context,
|
||||
&img,
|
||||
ofmt.clone(),
|
||||
max_bytes,
|
||||
&mut encoded,
|
||||
)?)
|
||||
|| is_avatar
|
||||
&& (exceeds_wh
|
||||
|| exif.is_some() && {
|
||||
@@ -477,8 +488,7 @@ impl<'a> BlobObject<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if do_scale || exif.is_some() {
|
||||
if !encoded.is_empty() || exif.is_some() {
|
||||
// The file format is JPEG/PNG now, we may have to change the file extension
|
||||
if !matches!(fmt, ImageFormat::Jpeg)
|
||||
&& matches!(ofmt, ImageOutputFormat::Jpeg { .. })
|
||||
|
||||
@@ -462,6 +462,26 @@ async fn test_recode_image_balanced_png() {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_recode_image_balanced_png_huge() {
|
||||
let bytes = include_bytes!("../../test-data/image/screenshot-huge.png");
|
||||
|
||||
SendImageCheckMediaquality {
|
||||
viewtype: Viewtype::Image,
|
||||
media_quality_config: "0",
|
||||
bytes,
|
||||
extension: "jpg",
|
||||
original_width: 1618,
|
||||
original_height: 949,
|
||||
compressed_width: 1618,
|
||||
compressed_height: 949,
|
||||
..Default::default()
|
||||
}
|
||||
.test()
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_sticker_with_exif() {
|
||||
let bytes = include_bytes!("../../test-data/image/logo-exif.png");
|
||||
|
||||
@@ -34,7 +34,8 @@ 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!(msg.get_text().starts_with("test [Image – "));
|
||||
assert!(msg.get_text().ends_with(" KiB]"));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::EventType;
|
||||
use crate::chat;
|
||||
use crate::chat::send_msg;
|
||||
use crate::config::Config;
|
||||
use crate::constants;
|
||||
use crate::contact;
|
||||
use crate::download::{DownloadState, PRE_MSG_ATTACHMENT_SIZE_THRESHOLD, PostMsgMetadata};
|
||||
use crate::message::{Message, MessageState, Viewtype, delete_msgs, markseen_msgs};
|
||||
@@ -402,9 +403,11 @@ 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);
|
||||
let n_bytes: usize = msg.get_filebytes(bob).await?.unwrap().try_into().unwrap();
|
||||
assert!(100_000 < n_bytes);
|
||||
assert!(n_bytes <= constants::BALANCED_IMAGE_BYTES);
|
||||
assert_eq!(msg.get_height(), 1920);
|
||||
assert_eq!(msg.get_width(), 1080);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
BIN
test-data/image/screenshot-huge.png
Normal file
BIN
test-data/image/screenshot-huge.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 792 KiB |
Reference in New Issue
Block a user