-
-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Animated Sticker Size Issues via Gif compression #151
base: master
Are you sure you want to change the base?
Changes from all commits
29ecc1d
e23e2d2
dd5ab3f
30cc3db
148462c
db730f5
d1d2c79
83308f5
4edb9d9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,6 +63,7 @@ EWS 是兼容 EH Forwarder Bot 的微信从端,基于逆向工程的微 | |
- ffmpeg | ||
- libmagic | ||
- pillow | ||
- gifsicle | ||
|
||
安装与启用 | ||
---------- | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,8 +2,11 @@ | |
import base64 | ||
import io | ||
import os | ||
import subprocess | ||
import json | ||
from typing import Dict, Any, TYPE_CHECKING, List | ||
from tempfile import NamedTemporaryFile | ||
from typing import Dict, Any, TYPE_CHECKING, List, IO | ||
|
||
|
||
from ehforwarderbot.types import MessageID | ||
from .vendor.itchat import utils as itchat_utils | ||
|
@@ -221,3 +224,65 @@ def print_st(): | |
res += base64.b64encode(file.getvalue()).decode() | ||
res += print_st() | ||
return res | ||
|
||
|
||
if os.name == "nt": | ||
# Workaround for Windows which cannot open the same file as "read" twice. | ||
# Using stdin/stdout pipe for IO with ffmpeg. | ||
# Said to be only working with a few encodings. It seems that Telegram GIF | ||
# (MP4, h264, soundless) luckily felt in that range. | ||
# | ||
# See: https://etm.1a23.studio/issues/90 | ||
|
||
def gif_conversion(file: IO[bytes]) -> IO[bytes]: | ||
"""Convert Telegram GIF to real GIF, the NT way.""" | ||
file.seek(0) | ||
new_file_size = os.path.getsize(file.name) | ||
print(f"file_size: {new_file_size/1024}KB") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
if new_file_size > 1024 * 1024: | ||
# try to use gifsicle lossy compression | ||
compress_file = NamedTemporaryFile(suffix='.gif') | ||
subprocess.run(["gifsicle", "--resize-method=catrom", "--lossy=100", "-O2", "-o", compress_file.name, file.name], check=True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not using std I/O piping as commented above. |
||
new_file_size = os.path.getsize(compress_file.name) | ||
if new_file_size > 1024 * 1024: | ||
scales = [512, 480, 400, 360, 300, 256, 250, 200, 150, 100] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How are these values defined? |
||
for scale in scales: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it make sense to use binary search here? |
||
subprocess.run(["gifsicle", "--resize-method=catrom", "--resize-fit", f"{scale}x{scale}", "--lossy=100", "-O2", "-o", compress_file.name, file.name], check=True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not using std I/O piping as commented above. |
||
new_file_size = os.path.getsize(compress_file.name) | ||
print(f"new_file_size: {new_file_size/1024}KB after resize to {scale}x{scale}") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
if new_file_size < 1024 * 1024: | ||
break | ||
file.close() | ||
file = compress_file | ||
if new_file_size > 1024 * 1024: | ||
raise EFBMessageError( | ||
self._("Image size is too large. (IS02)")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use a different error code for every new |
||
file.seek(0) | ||
return file | ||
|
||
else: | ||
def gif_conversion(file: IO[bytes]) -> IO[bytes]: | ||
"""Convert Telegram GIF to real GIF, the non-NT way.""" | ||
file.seek(0) | ||
new_file_size = os.path.getsize(file.name) | ||
print(f"file_size: {new_file_size/1024}KB") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
if new_file_size > 1024 * 1024: | ||
# try to use gifsicle lossy compression | ||
compress_file = NamedTemporaryFile(suffix='.gif') | ||
subprocess.run(["gifsicle", "--resize-method=catrom", "--lossy=100", "-O2", "-o", compress_file.name, file.name], check=True) | ||
new_file_size = os.path.getsize(compress_file.name) | ||
if new_file_size > 1024 * 1024: | ||
scales = [512, 480, 400, 360, 300, 256, 250, 200, 150, 100] | ||
for scale in scales: | ||
subprocess.run(["gifsicle", "--resize-method=catrom", "--resize-fit", f"{scale}x{scale}", "--lossy=100", "-O2", "-o", compress_file.name, file.name], check=True) | ||
new_file_size = os.path.getsize(compress_file.name) | ||
print(f"new_file_size: {new_file_size/1024}KB after resize to {scale}x{scale}") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
if new_file_size < 1024 * 1024: | ||
break | ||
file.close() | ||
file = compress_file | ||
if new_file_size > 1024 * 1024: | ||
raise EFBMessageError( | ||
self._("Image size is too large. (IS02)")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use a different error code for every new |
||
file.seek(0) | ||
return file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dose this still use
ffmpeg
?