mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 09:26:29 +03:00
feat: better avatar quality (#6822)
this PR scaled avatars using the Triangle-filter, resulting in often better image quality and smaller files (5%). it comes at high costs, therefore, we do not do that unconditionally for each image sent, see comment in the code and https://github.com/chatmail/core/pull/6815 --------- Co-authored-by: iequidoo <117991069+iequidoo@users.noreply.github.com>
This commit is contained in:
15
src/blob.rs
15
src/blob.rs
@@ -432,7 +432,20 @@ impl<'a> BlobObject<'a> {
|
|||||||
if mem::take(&mut add_white_bg) {
|
if mem::take(&mut add_white_bg) {
|
||||||
self::add_white_bg(&mut img);
|
self::add_white_bg(&mut img);
|
||||||
}
|
}
|
||||||
let new_img = img.thumbnail(img_wh, img_wh);
|
|
||||||
|
// resize() results in often slightly better quality,
|
||||||
|
// however, comes at high price of being 4+ times slower than thumbnail().
|
||||||
|
// for a typical camera image that is sent, this may be a change from "instant" (500ms) to "long time waiting" (3s).
|
||||||
|
// as we do not have recoding in background while chat has already a preview,
|
||||||
|
// we vote for speed.
|
||||||
|
// exception is the avatar image: this is far more often sent than recoded,
|
||||||
|
// usually has less pixels by cropping, UI that needs to wait anyways,
|
||||||
|
// and also benefits from slightly better (5%) encoding of Triangle-filtered images.
|
||||||
|
let new_img = if is_avatar {
|
||||||
|
img.resize(img_wh, img_wh, image::imageops::FilterType::Triangle)
|
||||||
|
} else {
|
||||||
|
img.thumbnail(img_wh, img_wh)
|
||||||
|
};
|
||||||
|
|
||||||
if encoded_img_exceeds_bytes(
|
if encoded_img_exceeds_bytes(
|
||||||
context,
|
context,
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ async fn test_selfavatar_outside_blobdir() {
|
|||||||
let avatar_blob = t.get_config(Config::Selfavatar).await.unwrap().unwrap();
|
let avatar_blob = t.get_config(Config::Selfavatar).await.unwrap().unwrap();
|
||||||
let avatar_path = Path::new(&avatar_blob);
|
let avatar_path = Path::new(&avatar_blob);
|
||||||
assert!(
|
assert!(
|
||||||
avatar_blob.ends_with("1e08d1c9398297c21dd3820f7db2324.jpg"),
|
avatar_blob.ends_with("7dde69e06b5ae6c27520a436bbfd65b.jpg"),
|
||||||
"The avatar filename should be its hash, put instead it's {avatar_blob}"
|
"The avatar filename should be its hash, put instead it's {avatar_blob}"
|
||||||
);
|
);
|
||||||
let scaled_avatar_size = file_size(avatar_path).await;
|
let scaled_avatar_size = file_size(avatar_path).await;
|
||||||
@@ -226,7 +226,7 @@ async fn test_selfavatar_in_blobdir() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let avatar_cfg = t.get_config(Config::Selfavatar).await.unwrap().unwrap();
|
let avatar_cfg = t.get_config(Config::Selfavatar).await.unwrap().unwrap();
|
||||||
assert!(
|
assert!(
|
||||||
avatar_cfg.ends_with("ec054c444a5755adf2b0aaea40209f2.png"),
|
avatar_cfg.ends_with("d57cb5ce5f371531b6e1fb17b6dd1af.png"),
|
||||||
"Avatar file name {avatar_cfg} should end with its hash"
|
"Avatar file name {avatar_cfg} should end with its hash"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user