feat(plugins): 新增鲁迅说功能并优化图片处理逻辑

- 新增 `who_say.py` 插件,支持生成鲁迅说图片
- 优化 `get_image.py` 中的 `add_text_to_image` 方法,支持自定义文本位置
- 在 `path_config.py` 中新增 `who_say_path` 配置
- 更新 `check.py` 菜单列表,添加鲁迅说相关命令
This commit is contained in:
SlyAimer 2025-02-09 16:11:31 +08:00
parent 7264c56716
commit 043efd162c
7 changed files with 127 additions and 11 deletions

View file

@ -133,7 +133,7 @@ class rua():
"""
图文合成
"""
async def add_text_to_image(image_path, output_path,content,font_path, font_size, text_color, position):
async def add_text_to_image(image_path, output_path,content,font_path, font_size, text_color,text_position ,position):
"""
给图片添加文字
:param image_path: 输入图片的路径
@ -159,7 +159,7 @@ async def add_text_to_image(image_path, output_path,content,font_path, font_size
# 获取字符的宽度
char_width, _ = draw.textbbox((0, 0), char, font=font)[2:]
# 如果当前行的宽度加上字符宽度超过图片指定宽度,则换行
if current_width + char_width > image.width // 2: # 这里是图片的一半
if current_width + char_width > image.width * 9 // 10: # 这里是图片的十分之九
wrapped_text += "\n"
current_width = 0
# 将字符添加到当前行
@ -189,15 +189,23 @@ async def add_text_to_image(image_path, output_path,content,font_path, font_size
position = (0, image.height - text_height)
elif position == "bottom right corner":
position = (image.width - text_width, image.height - text_height)
elif position == "bottom left corner 9/10":
position = (0, image.height * 9 // 10 - text_height)
# 在图片上绘制文本
draw.multiline_text(position, wrapped_text, font=font, fill=text_color, align="center")
draw.multiline_text(position, wrapped_text, font=font, fill=text_color, align=text_position)
# 保存合成后的图片
image.save(output_path)
# 关闭图片
# image.close()
async def delete_file(file_path):
try:
os.remove(file_path)
except FileNotFoundError:
print(f"文件 {file_path} 不存在。")
except Exception as e:
print(f"删除文件时发生错误: {e}")
if __name__ == '__main__':
# print(get_smms_image_url())

View file

@ -15,6 +15,9 @@ rua_png = path+'/image/rua/'
# 喜报、悲报图片路径
good_bad = path+'/image/good_bad_news/'
#谁说 生成图片路径
who_say_path = path+'/image/who_say/'
# 字体路径
font_path = path + '/font/'

View file

@ -15,7 +15,8 @@ import psutil
import time
menu = ['/今日运势','/今日塔罗','/图','/点歌','/摸摸头','/群老婆','/今日老婆', "/开启ai","/关闭ai","/角色列表","/添加人设", "/更新人设", "/删除人设", "/切换人设", "/管理员注册",
'/待办', '/test','/天气','我喜欢你', "", "/待办查询", "/新建待办", "/删除待办" ,"/cf","/B站搜索", "/BV搜索", "/喜报", "/悲报", "/奶龙", "/repo", "/info", "/menu"]
'/待办', '/test','/天气','我喜欢你', "", "/待办查询", "/新建待办", "/删除待办" ,"/cf","/B站搜索", "/BV搜索", "/喜报", "/悲报", "/luxun","/鲁迅说",
"/奶龙", "/repo", "/info", "/menu"]
async def check_value_in_menu(message: MessageEvent) -> bool:

View file

@ -6,7 +6,7 @@ import urllib.parse
import requests
import time
import httpx
from src.clover_image.get_image import add_text_to_image
from src.clover_image.get_image import add_text_to_image,delete_file
from src.configs.path_config import font_path,good_bad,temp_path
# good_news = on_command("喜报", rule=to_me(), priority=10, block=True, aliases={"悲报"})
@ -42,16 +42,20 @@ good_news = on_command("喜报", rule=to_me(), priority=10, block=True, aliases=
@good_news.handle()
async def function(message: MessageEvent):
value = message.get_plaintext().split(" ")
filename = ""
keyword,content = value[0], value[1]
if len(value) < 2 or len(value) > 2:
await good_news.finish("请输入 正确的格式哦~ /喜报+内容 或者 /悲报+内容")
if keyword == "/喜报":
await add_text_to_image(image_path=good_bad + "good_news.png", output_path=temp_path+"good_news.png", content=content,
filename = "good_news.png"
await add_text_to_image(image_path=good_bad + filename, output_path=temp_path + filename, content=content,
font_path=font_path + "msyh.ttc", font_size=64, text_color=(255, 0, 0),
position="center")
await good_news.finish(MessageSegment.file_image(Path(temp_path+"good_news.png")))
await good_news.finish(MessageSegment.file_image(Path(temp_path + filename)))
elif keyword == "/悲报":
await add_text_to_image(image_path=good_bad + "bad_news.png", output_path=temp_path+"bad_news.png", content=content,
font_path=font_path + "msyh.ttc", font_size=64, text_color=(128, 128, 128),
filename = "bad_news.png"
await add_text_to_image(image_path=good_bad + filename, output_path=temp_path + filename, content=content,
font_path=font_path + "msyh.ttc", font_size=64, text_color=(128, 128, 128),text_position="center",
position="center")
await good_news.finish(MessageSegment.file_image(Path(temp_path+"bad_news.png")))
await good_news.send(MessageSegment.file_image(Path(temp_path+filename)))
await delete_file(temp_path + filename)

View file

@ -0,0 +1,75 @@
import random
# 中文数字映射
chinese_numbers = ['', '', '', '', '', '', '', '', '', '']
# 生成对称且带有一个不同字符的矩阵
def generate_matrix(rows=9, cols=9):
base_char = ''
special_char = ''
matrix = [[base_char] * cols for _ in range(rows)]
# 确保矩阵对称
for i in range(rows):
for j in range(i, cols):
matrix[j][i] = matrix[i][j]
# 随机选择一个位置放置不同字符
diff_row = random.randint(0, rows - 1)
diff_col = random.randint(0, cols - 1)
matrix[diff_row][diff_col] = special_char
# 保持对称
matrix[diff_col][diff_row] = special_char
return matrix
# 打印矩阵,使用中文数字表示行号和列号
def print_matrix(matrix):
col_num = len(matrix[0])
# 打印列数头部
col_header = " " + " ".join([chinese_numbers[i + 1] for i in range(col_num)])
print(f"{chinese_numbers[0]} |{col_header}")
# 打印分隔线
print(" " + "——" * (len(col_header)))
for i, row in enumerate(matrix, start=1):
row_str = " ".join(row)
print(f"{chinese_numbers[i]} | {row_str}")
# 主游戏函数
def play_game():
matrix = generate_matrix()
print("矩阵:")
print_matrix(matrix)
while True:
try:
row_input = input("请输入不同字符所在的行(如 一),输入 '退出' 结束游戏: ")
if row_input == '退出':
print("游戏结束。")
break
col_input = input("请输入不同字符所在的列(如 一): ")
row_answer = chinese_numbers.index(row_input) - 1
col_answer = chinese_numbers.index(col_input) - 1
# 找出实际不同字符的位置
for i in range(len(matrix)):
for j in range(len(matrix[0])):
if matrix[i][j] != '':
correct_row = i
correct_col = j
break
if row_answer == correct_row and col_answer == correct_col:
print("恭喜你,回答正确!")
break
else:
print("回答错误,请再试一次。")
except ValueError:
print("输入无效,请输入正确的中文数字或 '退出'")
if __name__ == "__main__":
play_game()

25
src/plugins/who_say.py Normal file
View file

@ -0,0 +1,25 @@
import random
from pathlib import Path
from nonebot.plugin import on_command
from nonebot.adapters.qq import MessageEvent, MessageSegment
from src.clover_image.get_image import add_text_to_image,delete_file
from src.configs.path_config import who_say_path,font_path,temp_path
luxun = on_command("luxun", aliases={"鲁迅说"}, rule=None)
@luxun.handle()
async def handle(message: MessageEvent):
filename = str(message.get_user_id()) + str(random.randint(0, 10000)) + ".jpg"
value = message.get_plaintext().split(" ")
keyword, content = value[0], value[1]
if len(value) < 2 or len(value) > 2:
await luxun.finish("你让鲁迅说点啥?格式不对自己捋一捋吧~")
if len(content) >= 24:
await luxun.finish("太长了, 鲁迅说不完! 24字以内~")
else:
await add_text_to_image(image_path=who_say_path + "luxun.jpg", output_path=temp_path + filename, content=" "+content+" —鲁迅",
font_path=font_path + "华文行楷.TTF", font_size=28, text_color=(255, 255, 255),text_position="left",
position="bottom left corner 9/10")
await luxun.send(MessageSegment.file_image(Path(temp_path + filename)))
await delete_file(temp_path + filename)

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB