Files
konabot/konabot/plugins/notice_ui/notice.py
MixBadGun 35f411fb3a
All checks were successful
continuous-integration/drone/push Build is passing
提醒UI的GIF实现与参数传递
2025-12-04 16:20:09 +08:00

69 lines
2.5 KiB
Python

from io import BytesIO
import random
from PIL import Image
from konabot.common.web_render import konaweb
from konabot.common.web_render.core import WebRenderer
import numpy as np
from playwright.async_api import Page
class NoticeUI:
@staticmethod
async def render_notice(title: str, message: str) -> bytes:
"""
渲染一个通知图片,包含标题和消息内容。
"""
async def page_function(page: Page):
# 直到 setMaskMode 函数加载完成
await page.wait_for_function("typeof setMaskMode === 'function'", timeout=1000)
await page.evaluate('setMaskMode(false)')
# 直到 setContent 函数加载完成
await page.wait_for_function("typeof setContent === 'function'", timeout=1000)
# 设置标题和消息内容
await page.evaluate("""([title, message]) => {
return setContent(title, message);
}""",
[title, message])
async def mask_function(page: Page):
# 直到 setContent 函数加载完成
await page.wait_for_function("typeof setContent === 'function'", timeout=1000)
# 设置标题和消息内容
await page.evaluate("""([title, message]) => {
return setContent(title, message);
}""",
[title, message])
# 直到 setMaskMode 函数加载完成
await page.wait_for_function("typeof setMaskMode === 'function'", timeout=1000)
await page.evaluate('setMaskMode(true)')
image_bytes = await WebRenderer.render_with_persistent_page(
"notice_renderer",
konaweb('notice'),
target='#main',
other_function=page_function,
)
mask_bytes = await WebRenderer.render_with_persistent_page(
"notice_renderer",
konaweb('notice'),
target='#main',
other_function=mask_function)
image = Image.open(BytesIO(image_bytes)).convert("RGBA")
mask = Image.open(BytesIO(mask_bytes)).convert("L")
# 遮罩抖动二值化
mask = mask.convert('1') # 先转换为1位图像
image.putalpha(mask)
# 保存为GIF
output_buffer = BytesIO()
image.save(
output_buffer,
format="GIF",
disposal=2
)
output_buffer.seek(0)
return output_buffer.getvalue()