From 77ba732eec7660fbc3ebf059effa128b9fe9a049 Mon Sep 17 00:00:00 2001 From: Randall Lawrence Date: Sat, 21 Sep 2019 01:45:56 +0300 Subject: [PATCH] Added function to convert tgs to png. XXX: there is the bug in tgs lib, it crashes on some tgs files. Also cairo svg2png need to be called not from tgs.exporters because there is no option to set image size --- mautrix_telegram/util/file_transfer.py | 44 +++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/mautrix_telegram/util/file_transfer.py b/mautrix_telegram/util/file_transfer.py index 02a3e7ca..a40c280e 100644 --- a/mautrix_telegram/util/file_transfer.py +++ b/mautrix_telegram/util/file_transfer.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . from typing import Optional, Tuple, Union, Dict -from io import BytesIO +from io import BytesIO, StringIO import time import logging import asyncio @@ -48,6 +48,17 @@ try: except ImportError: VideoFileClip = random = string = os = mimetypes = None +try: + import cairosvg + from tgs.parsers.tgs import parse_tgs as tgs_importer + from tgs.exporters import svg as tgs_svg_exporter +# from tgs.exporters import gif as tgs_gif_exporter +except (ImportError, OSError): + cairosvg = None + tgs_importer = None + tgs_svg_exporter = None +# tgs_gif_exporter = None + log: logging.Logger = logging.getLogger("mau.util") TypeLocation = Union[Document, InputDocumentFileLocation, InputPeerPhotoFileLocation, @@ -72,6 +83,32 @@ def convert_image(file: bytes, source_mime: str = "image/webp", target_type: str return source_mime, file, None, None +def convert_tgs(file: bytes) -> Tuple[str, bytes, Optional[int], Optional[int]]: + if cairosvg and tgs_importer and tgs_svg_exporter: + try: + with BytesIO(file) as fi: + animation = tgs_importer(fi) + """ + It's possible to convert to gif, but out animation is too big (~500KB), + Convert to mp4 needs opencv2 to be installed... + TODO: Maybe should create config parameter + """ + with StringIO() as svg, BytesIO() as fo: + frame = int(animation.out_point * 0.3) + w, h = 256, 256 + tgs_svg_exporter.export_svg(animation, svg, frame=frame) + svg.seek(0) + cairosvg.svg2png(file_obj=svg, write_to=fo, output_width=w, output_height=h) + out = fo.getvalue() + return "image/png", out, w, h + # Yep... some animations crash library... + except AttributeError: + log.exception("Error occurred while converting animated sticker") + else: + log.warning("Unable to convert animated sticker, install tgs and cairosvg packages") + return "application/gzip", file, None, None + + def _temp_file_name(ext: str) -> str: return ("/tmp/mxtg-video-" + "".join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10)) @@ -197,6 +234,11 @@ async def _unlocked_transfer_file_to_matrix(client: MautrixTelegramClient, inten mime_type = magic.from_buffer(file, mime=True) image_converted = False + if mime_type == "application/gzip" and is_sticker: + mime_type, file, width, height = convert_tgs(file) + image_converted = width is not None + thumbnail = None + if mime_type == "image/webp": new_mime_type, file, width, height = convert_image( file, source_mime="image/webp", target_type="png",