diff --git a/assets/img/meme/xiaomu.png b/assets/img/meme/xiaomu.png new file mode 100755 index 0000000..0d14f96 Binary files /dev/null and b/assets/img/meme/xiaomu.png differ diff --git a/konabot/plugins/memepack/__init__.py b/konabot/plugins/memepack/__init__.py index 9260d9d..c7e2091 100644 --- a/konabot/plugins/memepack/__init__.py +++ b/konabot/plugins/memepack/__init__.py @@ -1,6 +1,8 @@ from io import BytesIO from typing import Iterable, cast +import PIL.Image + from loguru import logger from nonebot import on_message from nonebot_plugin_alconna import ( @@ -18,7 +20,7 @@ from nonebot_plugin_alconna import ( from playwright.async_api import ConsoleMessage, Page from konabot.common.nb.match_keyword import match_keyword -from konabot.common.nb.extract_image import DepPILImage +from konabot.common.nb.extract_image import DepImageBytesOrNone, DepPILImage from konabot.common.web_render import konaweb from konabot.common.web_render.core import WebRenderer from konabot.common.web_render.host_images import host_tempdir @@ -35,6 +37,7 @@ from konabot.plugins.memepack.drawing.saying import ( draw_pt, draw_suan, draw_vr, + draw_xm ) from konabot.plugins.memepack.drawing.watermark import draw_doubao_watermark @@ -361,3 +364,33 @@ async def _(saying: list[str]): await vrsay.send(await UniMessage().image(raw=img_bytes).export()) + +xmsay = on_alconna( + Alconna( + "小睦说", + Args[ + "saying", + MultiVar(str, "*"), + Field(missing_tips=lambda: "你没有写小睦说了什么"), + ], + Args["image?", Image | None], + ), + use_cmd_start=True, + use_cmd_sep=False, + skip_for_unmatch=False, + aliases={"小睦想"}, +) + + +@xmsay.handle() +async def _(saying: list[str], image: DepImageBytesOrNone): + if image is not None: + img = PIL.Image.open(BytesIO(image)) + else: + img = None + img = await draw_xm("\n".join(saying), img) + img_bytes = BytesIO() + img.save(img_bytes, format="PNG") + + await xmsay.send(await UniMessage().image(raw=img_bytes).export()) + diff --git a/konabot/plugins/memepack/drawing/saying.py b/konabot/plugins/memepack/drawing/saying.py index 85eee9f..c41114a 100644 --- a/konabot/plugins/memepack/drawing/saying.py +++ b/konabot/plugins/memepack/drawing/saying.py @@ -7,23 +7,41 @@ import PIL.Image from konabot.common.path import ASSETS_PATH from konabot.common.utils.to_async import make_async -from .base.fonts import HARMONYOS_SANS_SC_BLACK, HARMONYOS_SANS_SC_REGULAR, LXGWWENKAI_REGULAR +from .base.fonts import ( + HARMONYOS_SANS_SC_BLACK, + HARMONYOS_SANS_SC_REGULAR, + LXGWWENKAI_REGULAR, +) -geimao_image = PIL.Image.open(ASSETS_PATH / "img" / "meme" / "geimao.jpg").convert("RGBA") +geimao_image = PIL.Image.open(ASSETS_PATH / "img" / "meme" / "geimao.jpg").convert( + "RGBA" +) pt_image = PIL.Image.open(ASSETS_PATH / "img" / "meme" / "ptsay.png").convert("RGBA") mnk_image = PIL.Image.open(ASSETS_PATH / "img" / "meme" / "mnksay.jpg").convert("RGBA") dasuan_image = PIL.Image.open(ASSETS_PATH / "img" / "meme" / "dss.png").convert("RGBA") -suan_image = PIL.Image.open(ASSETS_PATH / "img" / "meme" / "suanleba.png").convert("RGBA") -cute_ten_image = PIL.Image.open(ASSETS_PATH / "img" / "meme" / "tententen.png").convert("RGBA") +suan_image = PIL.Image.open(ASSETS_PATH / "img" / "meme" / "suanleba.png").convert( + "RGBA" +) +cute_ten_image = PIL.Image.open(ASSETS_PATH / "img" / "meme" / "tententen.png").convert( + "RGBA" +) kio_image = PIL.Image.open(ASSETS_PATH / "img" / "meme" / "kiosay.jpg").convert("RGBA") -vr_image = PIL.Image.open(ASSETS_PATH / 'img' / 'meme' / 'vr.jpg').convert("RGBA") +vr_image = PIL.Image.open(ASSETS_PATH / "img" / "meme" / "vr.jpg").convert("RGBA") +xm_image = PIL.Image.open(ASSETS_PATH / "img" / "meme" / "xiaomu.png").convert("RGBA") def _draw_geimao(saying: str): img = geimao_image.copy() with imagetext_py.Writer(img) as iw: iw.draw_text_wrapped( - saying, 960, 50, 0.5, 0, 1920, 240, HARMONYOS_SANS_SC_BLACK, + saying, + 960, + 50, + 0.5, + 0, + 1920, + 240, + HARMONYOS_SANS_SC_BLACK, imagetext_py.Paint.Color(imagetext_py.Color.from_hex("000000FF")), 0.8, imagetext_py.TextAlign.Center, @@ -42,7 +60,14 @@ def _draw_pt(saying: str): img = pt_image.copy() with imagetext_py.Writer(img) as iw: iw.draw_text_wrapped( - saying, 259, 278, 0.5, 0.5, 360, 48, HARMONYOS_SANS_SC_REGULAR, + saying, + 259, + 278, + 0.5, + 0.5, + 360, + 48, + HARMONYOS_SANS_SC_REGULAR, imagetext_py.Paint.Color(imagetext_py.Color.from_hex("000000FF")), 1.0, imagetext_py.TextAlign.Center, @@ -59,7 +84,14 @@ def _draw_mnk(saying: str): img = mnk_image.copy() with imagetext_py.Writer(img) as iw: iw.draw_text_wrapped( - saying, 540, 25, 0.5, 0, 1080, 120, HARMONYOS_SANS_SC_BLACK, + saying, + 540, + 25, + 0.5, + 0, + 1080, + 120, + HARMONYOS_SANS_SC_BLACK, imagetext_py.Paint.Color(imagetext_py.Color.from_hex("000000FF")), 0.8, imagetext_py.TextAlign.Center, @@ -81,7 +113,14 @@ def _draw_suan(saying: str, dasuan: bool = False): img = suan_image.copy() with imagetext_py.Writer(img) as iw: iw.draw_text_wrapped( - saying, 1020, 290, 0.5, 0.5, 400, 48, LXGWWENKAI_REGULAR, + saying, + 1020, + 290, + 0.5, + 0.5, + 400, + 48, + LXGWWENKAI_REGULAR, imagetext_py.Paint.Color(imagetext_py.Color.from_hex("000000FF")), 1.0, imagetext_py.TextAlign.Center, @@ -98,7 +137,14 @@ def _draw_cute_ten(saying: str): img = cute_ten_image.copy() with imagetext_py.Writer(img) as iw: iw.draw_text_wrapped( - saying, 390, 479, 0.5, 0.5, 760, 96, LXGWWENKAI_REGULAR, + saying, + 390, + 479, + 0.5, + 0.5, + 760, + 96, + LXGWWENKAI_REGULAR, imagetext_py.Paint.Color(imagetext_py.Color.from_hex("000000FF")), 1.0, imagetext_py.TextAlign.Center, @@ -116,7 +162,14 @@ def draw_kiosay(saying: str): img = kio_image.copy() with imagetext_py.Writer(img) as iw: iw.draw_text_wrapped( - saying, 450, 540, 0.5, 0.5, 900, 96, LXGWWENKAI_REGULAR, + saying, + 450, + 540, + 0.5, + 0.5, + 900, + 96, + LXGWWENKAI_REGULAR, imagetext_py.Paint.Color(imagetext_py.Color.from_hex("000000FF")), 1.0, imagetext_py.TextAlign.Center, @@ -131,12 +184,19 @@ def draw_vr(saying: str): w, h = img.size hw = 300 - img2 = PIL.Image.new("RGBA", (w, h + hw), 'white') + img2 = PIL.Image.new("RGBA", (w, h + hw), "white") img2.paste(img, (0, hw)) with imagetext_py.Writer(img2) as iw: iw.draw_text_wrapped( - saying, w // 2, hw // 2 + 15, 0.5, 0.5, w, 64, LXGWWENKAI_REGULAR, + saying, + w // 2, + hw // 2 + 15, + 0.5, + 0.5, + w, + 64, + LXGWWENKAI_REGULAR, imagetext_py.Paint.Color(imagetext_py.Color.from_hex("000000FF")), 1.0, imagetext_py.TextAlign.Center, @@ -145,3 +205,36 @@ def draw_vr(saying: str): return img2 + +@make_async +def draw_xm(saying: str, image: PIL.Image.Image | None = None): + img_base = PIL.Image.new("RGBA", xm_image.size, (255, 255, 255, 255)) + with imagetext_py.Writer(img_base) as iw: + iw.draw_text_wrapped( + saying, + 442, + 200, + 0.5, + 0.5, + 884, + 64, + LXGWWENKAI_REGULAR, + imagetext_py.Paint.Color(imagetext_py.Color.from_hex("000000FF")), + 1.0, + imagetext_py.TextAlign.Center, + draw_emojis=True, + ) + if image is not None: + image_r = image.copy().convert("RGBA") + + width, height = image_r.size + base_width = img_base.size[0] + height = int(height / width * base_width) + image_r = image_r.resize((base_width, height)) + + # try to align center + y = 215 - image_r.height // 2 + img_base.paste(image_r, (0, y), mask=image_r) + img_base.paste(xm_image, (0, 0), mask=xm_image) + return img_base +