From 191009372b4585fb6c94cc62ae2c4f337f00db10 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Fri, 5 Jun 2020 21:19:12 +0200 Subject: [PATCH 1/6] basically recode images --- src/blob.rs | 37 ++++++++++++++++++++++++++++++++++++- src/chat.rs | 6 ++++++ src/constants.rs | 6 ++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/blob.rs b/src/blob.rs index bbb5635c9..b01a42d46 100644 --- a/src/blob.rs +++ b/src/blob.rs @@ -8,9 +8,11 @@ use async_std::prelude::*; use async_std::{fs, io}; use image::GenericImageView; +use num_traits::FromPrimitive; use thiserror::Error; -use crate::constants::AVATAR_SIZE; +use crate::config::Config; +use crate::constants::*; use crate::context::Context; use crate::events::Event; @@ -377,6 +379,39 @@ impl<'a> BlobObject<'a> { Ok(()) } + + pub async fn recode_to_image_size(&self, context: &Context) -> Result<(), BlobError> { + let blob_abs = self.to_abs_path(); + let img = image::open(&blob_abs).map_err(|err| BlobError::RecodeFailure { + blobdir: context.get_blobdir().to_path_buf(), + blobname: blob_abs.to_str().unwrap_or_default().to_string(), + cause: err, + })?; + + let (img_wh, _quality) = + if MediaQuality::from_i32(context.get_config_int(Config::MediaQuality).await) + .unwrap_or_default() + == MediaQuality::Balanced + { + (BALANCED_IMAGE_SIZE, BALANCED_IMAGE_QUALITY) + } else { + (WORSE_IMAGE_SIZE, WORSE_IMAGE_QUALITY) + }; + + if img.width() <= img_wh && img.height() <= img_wh { + return Ok(()); + } + + let img = img.thumbnail(img_wh, img_wh); + + img.save(&blob_abs).map_err(|err| BlobError::WriteFailure { + blobdir: context.get_blobdir().to_path_buf(), + blobname: blob_abs.to_str().unwrap_or_default().to_string(), + cause: err, + })?; + + Ok(()) + } } impl<'a> fmt::Display for BlobObject<'a> { diff --git a/src/chat.rs b/src/chat.rs index 60aa036f7..f8ec64b45 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -1332,6 +1332,12 @@ async fn prepare_msg_blob(context: &Context, msg: &mut Message) -> Result<(), Er .ok_or_else(|| { format_err!("Attachment missing for message of type #{}", msg.viewtype) })?; + + if msg.viewtype == Viewtype::Image { + if blob.recode_to_image_size(context).await.is_err() { + warn!(context, "Cannot recode image, using original data"); + } + } msg.param.set(Param::File, blob.as_name()); if msg.viewtype == Viewtype::File || msg.viewtype == Viewtype::Image { diff --git a/src/constants.rs b/src/constants.rs index dbdad54db..9dcf9ab06 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -227,6 +227,12 @@ pub const DC_BOB_SUCCESS: i32 = 1; // max. width/height of an avatar pub const AVATAR_SIZE: u32 = 192; +// max. width/height of images +pub const BALANCED_IMAGE_SIZE: u32 = 1280; +pub const BALANCED_IMAGE_QUALITY: u32 = 85; +pub const WORSE_IMAGE_SIZE: u32 = 640; +pub const WORSE_IMAGE_QUALITY: u32 = 75; + // this value can be increased if the folder configuration is changed and must be redone on next program start pub const DC_FOLDERS_CONFIGURED_VERSION: i32 = 3; From d5ea4f9b1a03655b87eb2dc1bcda3f4d2d7ab552 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Fri, 5 Jun 2020 23:51:32 +0200 Subject: [PATCH 2/6] make clippy happy --- src/blob.rs | 10 ++++++++++ src/chat.rs | 6 ++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/blob.rs b/src/blob.rs index b01a42d46..882af4fa7 100644 --- a/src/blob.rs +++ b/src/blob.rs @@ -15,6 +15,7 @@ use crate::config::Config; use crate::constants::*; use crate::context::Context; use crate::events::Event; +use crate::message; /// Represents a file in the blob directory. /// @@ -382,6 +383,15 @@ impl<'a> BlobObject<'a> { pub async fn recode_to_image_size(&self, context: &Context) -> Result<(), BlobError> { let blob_abs = self.to_abs_path(); + match message::guess_msgtype_from_suffix(Path::new(&blob_abs)) { + None => return Ok(()), + Some(imgtype) => { + if imgtype.1 != "image/jpeg" { + return Ok(()); + } + } + } + let img = image::open(&blob_abs).map_err(|err| BlobError::RecodeFailure { blobdir: context.get_blobdir().to_path_buf(), blobname: blob_abs.to_str().unwrap_or_default().to_string(), diff --git a/src/chat.rs b/src/chat.rs index f8ec64b45..75e52d28f 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -1333,10 +1333,8 @@ async fn prepare_msg_blob(context: &Context, msg: &mut Message) -> Result<(), Er format_err!("Attachment missing for message of type #{}", msg.viewtype) })?; - if msg.viewtype == Viewtype::Image { - if blob.recode_to_image_size(context).await.is_err() { - warn!(context, "Cannot recode image, using original data"); - } + if msg.viewtype == Viewtype::Image && blob.recode_to_image_size(context).await.is_err() { + warn!(context, "Cannot recode image, using original data"); } msg.param.set(Param::File, blob.as_name()); From 34c69785d0e42d10d12a8ce1bb36dd9170e8f869 Mon Sep 17 00:00:00 2001 From: bjoern Date: Sun, 7 Jun 2020 15:37:05 +0200 Subject: [PATCH 3/6] Update src/blob.rs Co-authored-by: Hocuri --- src/blob.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/blob.rs b/src/blob.rs index 882af4fa7..3bcadcac9 100644 --- a/src/blob.rs +++ b/src/blob.rs @@ -398,15 +398,14 @@ impl<'a> BlobObject<'a> { cause: err, })?; - let (img_wh, _quality) = - if MediaQuality::from_i32(context.get_config_int(Config::MediaQuality).await) - .unwrap_or_default() - == MediaQuality::Balanced - { - (BALANCED_IMAGE_SIZE, BALANCED_IMAGE_QUALITY) - } else { - (WORSE_IMAGE_SIZE, WORSE_IMAGE_QUALITY) - }; + let img_wh = if MediaQuality::from_i32(context.get_config_int(Config::MediaQuality).await) + .unwrap_or_default() + == MediaQuality::Balanced + { + BALANCED_IMAGE_SIZE + } else { + WORSE_IMAGE_SIZE + }; if img.width() <= img_wh && img.height() <= img_wh { return Ok(()); From 945943a8492493c08e6dfe1d7b8cd97765829035 Mon Sep 17 00:00:00 2001 From: bjoern Date: Sun, 7 Jun 2020 15:37:29 +0200 Subject: [PATCH 4/6] Update src/constants.rs Co-authored-by: Hocuri --- src/constants.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/constants.rs b/src/constants.rs index 9dcf9ab06..0e23e0ceb 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -229,9 +229,7 @@ pub const AVATAR_SIZE: u32 = 192; // max. width/height of images pub const BALANCED_IMAGE_SIZE: u32 = 1280; -pub const BALANCED_IMAGE_QUALITY: u32 = 85; pub const WORSE_IMAGE_SIZE: u32 = 640; -pub const WORSE_IMAGE_QUALITY: u32 = 75; // this value can be increased if the folder configuration is changed and must be redone on next program start pub const DC_FOLDERS_CONFIGURED_VERSION: i32 = 3; From 17283c86a3ce7435cb5554acf2b9a15739c100c8 Mon Sep 17 00:00:00 2001 From: bjoern Date: Sun, 7 Jun 2020 15:44:23 +0200 Subject: [PATCH 5/6] Update src/chat.rs Co-authored-by: Hocuri --- src/chat.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index 75e52d28f..abc3fed4e 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -1333,8 +1333,10 @@ async fn prepare_msg_blob(context: &Context, msg: &mut Message) -> Result<(), Er format_err!("Attachment missing for message of type #{}", msg.viewtype) })?; - if msg.viewtype == Viewtype::Image && blob.recode_to_image_size(context).await.is_err() { - warn!(context, "Cannot recode image, using original data"); + if msg.viewtype == Viewtype::Image { + if let Err(e) = blob.recode_to_image_size(context).await { + warn!(context, "Cannot recode image, using original data: {:?}", e); + } } msg.param.set(Param::File, blob.as_name()); From f3a59e19d8fc946e2e08245a4b88b11cd1b88cf4 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Sun, 7 Jun 2020 15:56:48 +0200 Subject: [PATCH 6/6] simplify condition for jpeg-check --- src/blob.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/blob.rs b/src/blob.rs index 3bcadcac9..331dcc282 100644 --- a/src/blob.rs +++ b/src/blob.rs @@ -383,13 +383,10 @@ impl<'a> BlobObject<'a> { pub async fn recode_to_image_size(&self, context: &Context) -> Result<(), BlobError> { let blob_abs = self.to_abs_path(); - match message::guess_msgtype_from_suffix(Path::new(&blob_abs)) { - None => return Ok(()), - Some(imgtype) => { - if imgtype.1 != "image/jpeg" { - return Ok(()); - } - } + if message::guess_msgtype_from_suffix(Path::new(&blob_abs)) + != Some((Viewtype::Image, "image/jpeg")) + { + return Ok(()); } let img = image::open(&blob_abs).map_err(|err| BlobError::RecodeFailure {