mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
feat: Optimize avatar size multiplier for 2 << n px avatars
Instead of 2/3 which is not optimal for 512 px avatars usually passed to Core, use the sequence 7/8, 6/8, 11/16, 10/16... to do "smaller" downscaling steps and reduce aliasing effects. Before, it was discussed that just 3/4 can be used. However: - If we repeat the downscaling step, we get `3 ** n` as a numerator and this way increase aliasing effects on each step. The same for 7/8. Better limit the numerator value. - As we do downscaling in a loop only for avatars which aren't changed frequently, let's do "smaller" steps and start from 7/8.
This commit is contained in:
@@ -435,6 +435,8 @@ impl<'a> BlobObject<'a> {
|
||||
});
|
||||
|
||||
if do_scale {
|
||||
let (mut m, mut d) = (8, 8);
|
||||
let wh = target_wh;
|
||||
loop {
|
||||
if mem::take(&mut add_white_bg) {
|
||||
self::add_white_bg(&mut img);
|
||||
@@ -467,8 +469,11 @@ impl<'a> BlobObject<'a> {
|
||||
"Failed to scale image to below {max_bytes}B.",
|
||||
));
|
||||
}
|
||||
|
||||
target_wh = target_wh * 2 / 3;
|
||||
(m, d) = match m > 6 {
|
||||
true => (m - 1, d),
|
||||
false => (11, d * 2),
|
||||
};
|
||||
target_wh = wh * m / d;
|
||||
} else {
|
||||
info!(
|
||||
context,
|
||||
|
||||
@@ -4,7 +4,9 @@ use super::*;
|
||||
use crate::message::{Message, Viewtype};
|
||||
use crate::param::Param;
|
||||
use crate::sql;
|
||||
use crate::test_utils::{self, AVATAR_64x64_BYTES, AVATAR_64x64_DEDUPLICATED, TestContext};
|
||||
use crate::test_utils::{
|
||||
self, AVATAR_64x64_BYTES, AVATAR_64x64_DEDUPLICATED, TestContext, TestContextManager,
|
||||
};
|
||||
use crate::tools::SystemTime;
|
||||
|
||||
fn check_image_size(path: impl AsRef<Path>, width: u32, height: u32) -> image::DynamicImage {
|
||||
@@ -239,6 +241,22 @@ async fn test_selfavatar_in_blobdir() {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_huge_selfavatar() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let t = &tcm.unconfigured().await;
|
||||
let avatar_src = t.get_blobdir().join("avatar.png");
|
||||
let bytes = include_bytes!("../../test-data/image/noise400x400.png");
|
||||
|
||||
fs::write(&avatar_src, bytes).await?;
|
||||
t.set_config(Config::Selfavatar, Some(avatar_src.to_str().unwrap()))
|
||||
.await?;
|
||||
let avatar_cfg = t.get_config(Config::Selfavatar).await?.unwrap();
|
||||
// At 6/8 the avatar is still huge, so it's downscaled to 11/16.
|
||||
check_image_size(avatar_cfg, 275, 275);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_selfavatar_copy_without_recode() {
|
||||
let t = TestContext::new().await;
|
||||
|
||||
BIN
test-data/image/noise400x400.png
Normal file
BIN
test-data/image/noise400x400.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 470 KiB |
Reference in New Issue
Block a user