From 04f94ca8e9bcc0653d57c154d9fb9c302937a1b0 Mon Sep 17 00:00:00 2001 From: xtaodada Date: Sun, 11 Jul 2021 14:41:04 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=E2=9A=A1=EF=B8=8F=20pic2sticker=20?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E8=BD=AC=E8=B4=B4=E7=BA=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- list.json | 14 ++++- pic2sticker.py | 151 ++++++++++++++++++++++++++++++++++++++++++++++++ stickertopic.py | 18 +++--- 3 files changed, 172 insertions(+), 11 deletions(-) create mode 100644 pic2sticker.py diff --git a/list.json b/list.json index 78f3531..193ad23 100644 --- a/list.json +++ b/list.json @@ -332,13 +332,13 @@ }, { "name": "stickertopic", - "version": "1.11", + "version": "1.111", "section": "chat", "maintainer": "TNTcraftHIM", "size": "3.5 kb", "supported": true, "des-short": "贴纸转图片", - "des": "把别人发的贴纸转换成图片(只支持静态)。命令:pic。" + "des": "把别人发的贴纸转换成图片(只支持静态)。命令:stickertopic 。" }, { "name": "vip", @@ -549,6 +549,16 @@ "supported": true, "des-short": "删除烦人的贴纸", "des": "删除最近 50 条消息中的 sticker 。" + }, + { + "name": "pic2sticker", + "version": "1.0", + "section": "chat", + "maintainer": "xtaodada", + "size": "4.7 kb", + "supported": true, + "des-short": "图片转贴纸", + "des": "把别人发的图片转换成贴纸(只支持静态)。命令:pic2sticker 。" } ] } diff --git a/pic2sticker.py b/pic2sticker.py new file mode 100644 index 0000000..7a64e8b --- /dev/null +++ b/pic2sticker.py @@ -0,0 +1,151 @@ +""" PagerMaid module to handle sticker collection. """ + +from io import BytesIO +from telethon.tl.types import DocumentAttributeFilename, MessageMediaPhoto +from PIL import Image, ImageOps +from math import floor +from pagermaid import bot, redis, redis_status +from pagermaid.listener import listener +from pagermaid.utils import lang, alias_command + + +@listener(is_plugin=False, outgoing=True, command=alias_command("pic2sticker"), + description='将图片转换为贴纸', + parameters="") +async def pic2sticker(context): + """ Fetches images and send it as sticker. """ + pic_round = False + if len(context.parameter) >= 1: + pic_round = True + + if redis_status(): + if redis.get("sticker.round"): + pic_round = True + + message = await context.get_reply_message() + if message and message.media: + if isinstance(message.media, MessageMediaPhoto): + photo = BytesIO() + photo = await bot.download_media(message.photo, photo) + elif "image" in message.media.document.mime_type.split('/'): + photo = BytesIO() + try: + await context.edit(lang('sticker_downloading')) + except: + pass + await bot.download_file(message.media.document, photo) + if (DocumentAttributeFilename(file_name='sticker.webp') in + message.media.document.attributes): + try: + await context.edit(lang('sticker_type_not_support')) + except: + pass + return + else: + try: + await context.edit(lang('sticker_type_not_support')) + except: + pass + return + else: + try: + await context.edit(lang('sticker_reply_not_sticker')) + except: + pass + return + + if photo: + file = BytesIO() + try: + await context.edit(lang('sticker_resizing')) + except: + pass + image = await resize_image(photo) + if pic_round: + try: + await context.edit(lang('us_static_rounding')) + except: + pass + image = await rounded_image(image) + file.name = "sticker.webp" + image.save(file, "WEBP") + file.seek(0) + try: + await context.edit(lang('us_static_uploading')) + except: + pass + await bot.send_file(context.chat_id, file, force_document=False) + try: + await context.delete() + except: + pass + + +async def resize_image(photo): + image = Image.open(photo) + maxsize = (512, 512) + if (image.width and image.height) < 512: + size1 = image.width + size2 = image.height + if image.width > image.height: + scale = 512 / size1 + size1new = 512 + size2new = size2 * scale + else: + scale = 512 / size2 + size1new = size1 * scale + size2new = 512 + size1new = floor(size1new) + size2new = floor(size2new) + size_new = (size1new, size2new) + image = image.resize(size_new) + else: + image.thumbnail(maxsize) + + return image + + +async def rounded_image(image): + w = image.width + h = image.height + # 比较长宽 + if w > h: + resize_size = h + else: + resize_size = w + half_size = floor(resize_size / 2) + + # 获取圆角模版,切割成4个角 + tl = (0, 0, 256, 256) + tr = (256, 0, 512, 256) + bl = (0, 256, 256, 512) + br = (256, 256, 512, 512) + border = Image.open('pagermaid/static/images/rounded.png').convert('L') + tlp = border.crop(tl) + trp = border.crop(tr) + blp = border.crop(bl) + brp = border.crop(br) + + # 缩放四个圆角 + tlp = tlp.resize((half_size, half_size)) + trp = trp.resize((half_size, half_size)) + blp = blp.resize((half_size, half_size)) + brp = brp.resize((half_size, half_size)) + + # 扩展四个角大小到目标图大小 + # tlp = ImageOps.expand(tlp, (0, 0, w - tlp.width, h - tlp.height)) + # trp = ImageOps.expand(trp, (w - trp.width, 0, 0, h - trp.height)) + # blp = ImageOps.expand(blp, (0, h - blp.height, w - blp.width, 0)) + # brp = ImageOps.expand(brp, (w - brp.width, h - brp.height, 0, 0)) + + # 四个角合并到一张新图上 + ni = Image.new('RGB', (w, h), (0, 0, 0)).convert('L') + ni.paste(tlp, (0, 0)) + ni.paste(trp, (w - trp.width, 0)) + ni.paste(blp, (0, h - blp.height)) + ni.paste(brp, (w - brp.width, h - brp.height)) + + # 合并圆角和原图 + image.putalpha(ImageOps.invert(ni)) + + return image diff --git a/stickertopic.py b/stickertopic.py index 06a2e04..5c35eb0 100644 --- a/stickertopic.py +++ b/stickertopic.py @@ -9,21 +9,21 @@ from pagermaid.utils import alias_command from random import random -@listener(outgoing=True, command=alias_command("pic"), +@listener(outgoing=True, command=alias_command("stickertopic"), description="将你回复的静态贴纸转换为图片", parameters="(是否发送原图,默认为n)") async def stickertopic(context): try: if len(context.parameter) >= 1: - if context.parameter[0][0].lower()=="y": - as_file=True - elif context.parameter[0][0].lower()=="n": - as_file=False + if context.parameter[0][0].lower() == "y": + as_file = True + elif context.parameter[0][0].lower() == "n": + as_file = False elif not context.parameter[0]: - as_file=False + as_file = False else: raise IndexError else: - as_file=False + as_file = False except: await context.edit("出错了呜呜呜 ~ 无效的参数。") return @@ -78,7 +78,7 @@ async def stickertopic(context): if not animated: await context.edit("正在转换...\n███████70%") image = Image.open(photo) - filename = "sticker"+str(random())[2:]+".png" + filename = "sticker" + str(random())[2:] + ".png" image.save(filename, "PNG") else: await context.edit("出错了呜呜呜 ~ 目标不是**静态**贴纸 。") @@ -86,7 +86,7 @@ async def stickertopic(context): await context.delete() return await context.edit("正在上传...\n██████████99%") - await bot.send_file(context.chat_id,filename, force_document=as_file) + await bot.send_file(context.chat_id, filename, force_document=as_file) try: await context.delete() except: