From ca8c57798df7aa54aa85acb50ca0e3905929764e Mon Sep 17 00:00:00 2001 From: Rongrong Date: Sun, 10 Dec 2023 05:05:36 +0800 Subject: [PATCH] fix(parsing/medium): weserv img still too big Signed-off-by: Rongrong --- docs/CHANGELOG.md | 1 + docs/CHANGELOG.zh.md | 1 + src/parsing/medium.py | 18 ++++++++++++++---- src/parsing/post_formatter.py | 4 ++-- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 9d7537a70f..e61046c3cf 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -9,6 +9,7 @@ ### Bug fixes - **"Remote" `/test` unavailable**: Fix a bug preventing the bot manager from using the `/test` command "remotely". +- **Resized images still too big**: Fix a bug causing images resized by `wsrv.nl` to be sometimes too big (exceed the 5MiB limitation of Telegram DC) to send. ## Significant performance improvement, native blockquote and syntax highlighting (v2.4.0) diff --git a/docs/CHANGELOG.zh.md b/docs/CHANGELOG.zh.md index 5970e4831a..fa5339a1d4 100644 --- a/docs/CHANGELOG.zh.md +++ b/docs/CHANGELOG.zh.md @@ -9,6 +9,7 @@ ### Bug 修复 - **“远程” `/test` 不可用**:修复阻止 bot 管理员“远程”使用 `/test` 命令的错误。 +- **调节尺寸后的图像仍然太大**: 修复了一个错误,这个错误导致经过 `wsrv.nl` 调节尺寸后的图像有时候仍然太大(超过 Telegram DC 的 5MiB 限制)以至于无法发送。 ## 显著提高性能、原生块状引用和语法高亮(v2.4.0) diff --git a/src/parsing/medium.py b/src/parsing/medium.py index cdb4c0adbb..91c4459db4 100644 --- a/src/parsing/medium.py +++ b/src/parsing/medium.py @@ -562,7 +562,7 @@ def __init__(self, urls: Union[str, list[str]]): self.urls = new_urls self.type_fallback_urls = new_urls.copy() urls_not_weserv = [url for url in self.urls if not url.startswith(env.IMAGES_WESERV_NL)] - self.urls.extend(construct_weserv_url_convert_to_2560_png(urls_not_weserv[i]) + self.urls.extend(construct_weserv_url_convert_to_2560(urls_not_weserv[i]) for i in range(min(len(urls_not_weserv), 3))) # use for final fallback self.chosen_url = self.urls[0] @@ -981,6 +981,7 @@ def construct_weserv_url(url: str, height: Optional[int] = None, fit: Optional[str] = None, output_format: Optional[str] = None, + quality: Optional[int] = None, without_enlargement: Optional[bool] = None, default_image: Optional[str] = None) -> str: return ( @@ -990,18 +991,27 @@ def construct_weserv_url(url: str, + (f'&h={height}' if height else '') + (f'&fit={fit}' if fit else '') + (f'&output={output_format}' if output_format else '') + + (f'&q={quality}' if quality else '') + (f'&we=1' if without_enlargement else '') + (f'&default={weserv_param_encode(default_image)}' if default_image else '') ) -def construct_weserv_url_convert_to_2560_png(url: str) -> str: +def construct_weserv_url_convert_to_2560(url: str) -> str: return construct_weserv_url( url, width=2560, height=2560, - fit='inside', - output_format='png', + # fit='inside', # is default + output_format='jpg', + # In the worst case, 89% ensures the size won't exceed 5MB + # E.g.: + # 2560x2560 white noise truecolor --89% JPEG--> 4.98MiB + # 2560x2560 white noise truecolor --90% JPEG--> 10.26MiB + # See also: + # https://robson.plus/white-noise-image-generator/ + # https://fotoforensics.com/tutorial-estq.php + quality=89, without_enlargement=True ) diff --git a/src/parsing/post_formatter.py b/src/parsing/post_formatter.py index f58e0ed7eb..13b376410c 100644 --- a/src/parsing/post_formatter.py +++ b/src/parsing/post_formatter.py @@ -11,7 +11,7 @@ from .splitter import get_plain_text_length from .html_parser import parse from .html_node import * -from .medium import Media, Image, Video, Audio, File, Animation, construct_weserv_url_convert_to_2560_png +from .medium import Media, Image, Video, Audio, File, Animation, construct_weserv_url_convert_to_2560 AUTO: Final = 0 DISABLE: Final = -1 @@ -538,7 +538,7 @@ async def parse_html(self): medium = File(enclosure.url) elif any(keyword in enclosure.type for keyword in ('webp', 'svg')): medium = Image(enclosure.url) - medium.url = construct_weserv_url_convert_to_2560_png(enclosure.url) + medium.url = construct_weserv_url_convert_to_2560(enclosure.url) elif enclosure.type.startswith('image/gif'): medium = Animation(enclosure.url) elif enclosure.type.startswith('audio'):