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
This commit is contained in:
Randall Lawrence
2019-09-21 01:45:56 +03:00
parent 835175aa36
commit 77ba732eec
+43 -1
View File
@@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
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",