zhenxun_bot/plugins/update_picture.py

311 lines
12 KiB
Python
Raw Normal View History

2021-05-20 19:27:31 +08:00
from nonebot import on_command
from PIL import Image, ImageFilter
2021-07-30 21:21:51 +08:00
from utils.message_builder import image
2021-05-20 19:27:31 +08:00
from configs.path_config import IMAGE_PATH
from services.log import logger
from nonebot.rule import to_me
2021-07-30 21:21:51 +08:00
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
2021-05-20 19:27:31 +08:00
from nonebot.typing import T_State
2021-06-30 19:50:55 +08:00
from utils.utils import get_message_imgs
2021-11-23 21:44:59 +08:00
from pathlib import Path
2021-06-30 19:50:55 +08:00
from utils.utils import is_number, get_message_text
2021-07-30 21:21:51 +08:00
from utils.image_utils import CreateImg, pic2b64
2021-08-17 23:17:08 +08:00
from configs.config import NICKNAME
2021-11-23 21:44:59 +08:00
from utils.http_utils import AsyncHttpx
2021-05-20 19:27:31 +08:00
import cv2
import numpy as np
2021-10-03 14:24:07 +08:00
__zx_plugin_name__ = "各种图片简易操作"
__plugin_usage__ = """
usage
简易的基础图片操作输入 指定操作 序号 来进行选择
指令
1.修改尺寸 [] [] [图片]
2.等比压缩 [比例] [图片]
3.旋转图片 [角度] [图片]
4.水平翻转 [图片]
5.铅笔滤镜 [图片]
6.模糊效果 [图片]
7.锐化效果 [图片]
8.高斯模糊 [图片]
9.边缘检测 [图片]
10.底色替换 [/] [///绿/] [图片]
示例图片修改尺寸 100 200 [图片]
示例图片 2 0.3 [图片]
""".strip()
__plugin_des__ = "10种快捷的图片简易操作"
__plugin_cmd__ = [
"改图 修改尺寸 [宽] [高] [图片]",
"改图 等比压缩 [比例] [图片]",
"改图 旋转图片 [角度] [图片]",
"改图 水平翻转 [图片]",
"改图 铅笔滤镜 [图片]",
"改图 模糊效果 [图片]",
"改图 锐化效果 [图片]",
"改图 高斯模糊 [图片]",
"改图 边缘检测 [图片]",
"改图 底色替换 [红/蓝] [红/蓝/白/绿/黄] [图片]",
]
__plugin_type__ = ("一些工具", 1)
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["修改图片", "改图", "操作图片"],
}
2021-05-20 19:27:31 +08:00
# IMAGE_LOCAL = IMAGE_PATH + "temp/{}_update.png"
2021-07-30 21:21:51 +08:00
method_flag = ""
2021-05-20 19:27:31 +08:00
2021-07-30 21:21:51 +08:00
update_img = on_command(
2021-10-03 14:24:07 +08:00
"修改图片", aliases={"操作图片", "改图"}, priority=5, rule=to_me(), block=True
2021-07-30 21:21:51 +08:00
)
2021-05-20 19:27:31 +08:00
2021-07-30 21:21:51 +08:00
method_list = [
"修改尺寸",
"等比压缩",
"旋转图片",
"水平翻转",
"铅笔滤镜",
"模糊效果",
"锐化效果",
"高斯模糊",
"边缘检测",
"底色替换",
]
method_str = ""
2021-05-20 19:27:31 +08:00
method_oper = []
for i in range(len(method_list)):
2021-07-30 21:21:51 +08:00
method_str += f"\n{i + 1}.{method_list[i]}"
2021-05-20 19:27:31 +08:00
method_oper.append(method_list[i])
method_oper.append(str(i + 1))
update_img_help = CreateImg(960, 700, font_size=24)
update_img_help.text((10, 10), __plugin_usage__)
2021-07-30 21:21:51 +08:00
update_img_help.save(IMAGE_PATH + "update_img_help.png")
2021-05-20 19:27:31 +08:00
@update_img.args_parser
async def _(bot: Bot, event: MessageEvent, state: T_State):
global method_flag
2021-07-30 21:21:51 +08:00
if str(event.get_message()) in ["取消", "算了"]:
2021-05-20 19:27:31 +08:00
await update_img.finish("已取消操作..", at_sender=True)
2021-07-30 21:21:51 +08:00
if state["_current_key"] in ["method"]:
2021-05-20 19:27:31 +08:00
if str(event.get_message()) not in method_oper:
await update_img.reject(f"操作不正确,请重新输入!{method_str}")
state[state["_current_key"]] = str(event.get_message())
method_flag = str(event.get_message())
2021-07-30 21:21:51 +08:00
if method_flag in ["1", "修改尺寸"]:
if state["_current_key"] == "x":
2021-05-20 19:27:31 +08:00
if not is_number(str(event.get_message())):
await update_img.reject("宽度不正确!请重新输入数字...")
state[state["_current_key"]] = str(event.get_message())
2021-07-30 21:21:51 +08:00
if state["_current_key"] == "y":
2021-05-20 19:27:31 +08:00
if not is_number(str(event.get_message())):
await update_img.reject("长度不正确!请重新输入数字...")
state[state["_current_key"]] = str(event.get_message())
2021-07-30 21:21:51 +08:00
elif method_flag in ["2", "等比压缩", "3", "旋转图片"]:
if state["_current_key"] == "x":
2021-05-20 19:27:31 +08:00
if not is_number(str(event.get_message())):
await update_img.reject("比率不正确!请重新输入数字...")
state[state["_current_key"]] = str(event.get_message())
2021-07-30 21:21:51 +08:00
state["y"] = ""
elif method_flag in [
"4",
"水平翻转",
"5",
"铅笔滤镜",
"6",
"模糊效果",
"7",
"锐化效果",
"8",
"高斯模糊",
"9",
"边缘检测",
]:
state["x"] = ""
state["y"] = ""
elif method_flag in ["10", "底色替换"]:
if state["_current_key"] == "x":
if str(event.get_message()) not in ["红色", "蓝色", "", ""]:
await update_img.reject("请输入支持的被替换的底色:\n红色 蓝色")
state["x"] = str(event.get_message())
if state["_current_key"] == "y":
if str(event.get_message()) not in [
"红色",
"白色",
"蓝色",
"绿色",
"黄色",
"",
"",
"",
"绿",
"",
]:
await update_img.reject("请输入支持的替换的底色:\n红色 蓝色 白色 绿色")
state["y"] = str(event.get_message())
if state["_current_key"] == "imgs":
2021-05-20 19:27:31 +08:00
if not get_message_imgs(event.json()):
await update_img.reject("没图?没图?没图?来图速来!")
state[state["_current_key"]] = get_message_imgs(event.json())
@update_img.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
2021-07-30 21:21:51 +08:00
if str(event.get_message()) in ["帮助"]:
await update_img.finish(image("update_img_help.png"))
2021-05-20 19:27:31 +08:00
raw_arg = get_message_text(event.json())
img_list = get_message_imgs(event.json())
if raw_arg:
args = raw_arg.split("[")[0].split(" ")
print(args)
2021-07-30 21:21:51 +08:00
state["method"] = args[0]
2021-05-20 19:27:31 +08:00
if len(args) == 2:
2021-07-30 21:21:51 +08:00
if args[0] in ["等比压缩", "旋转图片"]:
2021-05-20 19:27:31 +08:00
if is_number(args[1]):
2021-07-30 21:21:51 +08:00
state["x"] = args[1]
state["y"] = ""
2021-05-20 19:27:31 +08:00
elif len(args) > 2:
if args[0] in ["修改尺寸"]:
if is_number(args[1]):
2021-07-30 21:21:51 +08:00
state["x"] = args[1]
2021-05-20 19:27:31 +08:00
if is_number(args[2]):
2021-07-30 21:21:51 +08:00
state["y"] = args[2]
if args[0] in ["底色替换"]:
if args[1] in ["红色", "蓝色", "", ""]:
state["x"] = args[1]
if args[2] in ["红色", "白色", "蓝色", "绿色", "黄色", "", "", "", "绿", ""]:
state["y"] = args[2]
if args[0] in ["水平翻转", "铅笔滤镜", "模糊效果", "锐化效果", "高斯模糊", "边缘检测"]:
state["x"] = ""
state["y"] = ""
2021-05-20 19:27:31 +08:00
if img_list:
2021-07-30 21:21:51 +08:00
state["imgs"] = img_list
2021-05-20 19:27:31 +08:00
@update_img.got("method", prompt=f"要使用图片的什么操作呢?{method_str}")
@update_img.got("x", prompt="[宽度? 比率? 旋转角度? 底色?]")
@update_img.got("y", prompt="[长度? 0 0 底色?]")
@update_img.got("imgs", prompt="图呢图呢图呢图呢GKD")
async def _(bot: Bot, event: MessageEvent, state: T_State):
2021-07-30 21:21:51 +08:00
method = state["method"]
x = state["x"] if state["x"] else ""
y = state["y"] if state["y"] else ""
img_list = state["imgs"]
2021-05-20 19:27:31 +08:00
if is_number(x):
x = float(x)
if is_number(y):
y = int(y)
index = 0
2021-07-30 21:21:51 +08:00
result = ""
2021-11-23 21:44:59 +08:00
for img_url in img_list:
if await AsyncHttpx.download_file(
img_url, Path(IMAGE_PATH) / "temp" / f"{event.user_id}_{index}_update.png"
):
index += 1
else:
await update_img.finish("获取图片超时了...", at_sender=True)
2021-05-20 19:27:31 +08:00
if index == 0:
return
2021-07-30 21:21:51 +08:00
if method in ["修改尺寸", "1"]:
2021-05-20 19:27:31 +08:00
for i in range(index):
2021-07-30 21:21:51 +08:00
img = Image.open(IMAGE_PATH + f"temp/{event.user_id}_{i}_update.png")
img = img.convert("RGB")
2021-05-20 19:27:31 +08:00
img = img.resize((int(x), int(y)), Image.ANTIALIAS)
result += image(b64=pic2b64(img))
await update_img.finish(result, at_sender=True)
2021-07-30 21:21:51 +08:00
if method in ["等比压缩", "2"]:
2021-05-20 19:27:31 +08:00
for i in range(index):
2021-07-30 21:21:51 +08:00
img = Image.open(IMAGE_PATH + f"temp/{event.user_id}_{i}_update.png")
2021-05-20 19:27:31 +08:00
width, height = img.size
2021-07-30 21:21:51 +08:00
img = img.convert("RGB")
2021-05-20 19:27:31 +08:00
if width * x < 8000 and height * x < 8000:
img = img.resize((int(x * width), int(x * height)))
result += image(b64=pic2b64(img))
else:
2021-08-17 23:17:08 +08:00
await update_img.finish(f"{NICKNAME}不支持图片压缩后宽或高大于8000的存在")
2021-07-30 21:21:51 +08:00
if method in ["旋转图片", "3"]:
2021-05-20 19:27:31 +08:00
for i in range(index):
2021-07-30 21:21:51 +08:00
img = Image.open(IMAGE_PATH + f"temp/{event.user_id}_{i}_update.png")
2021-05-20 19:27:31 +08:00
img = img.rotate(x)
result += image(b64=pic2b64(img))
2021-07-30 21:21:51 +08:00
if method in ["水平翻转", "4"]:
2021-05-20 19:27:31 +08:00
for i in range(index):
2021-07-30 21:21:51 +08:00
img = Image.open(IMAGE_PATH + f"temp/{event.user_id}_{i}_update.png")
2021-05-20 19:27:31 +08:00
img = img.transpose(Image.FLIP_LEFT_RIGHT)
result += image(b64=pic2b64(img))
2021-07-30 21:21:51 +08:00
if method in ["铅笔滤镜", "5"]:
2021-05-20 19:27:31 +08:00
for i in range(index):
2021-07-30 21:21:51 +08:00
img = Image.open(
IMAGE_PATH + f"temp/{event.user_id}_{i}_update.png"
).filter(ImageFilter.CONTOUR)
2021-05-20 19:27:31 +08:00
result += image(b64=pic2b64(img))
2021-07-30 21:21:51 +08:00
if method in ["模糊效果", "6"]:
2021-05-20 19:27:31 +08:00
for i in range(index):
2021-07-30 21:21:51 +08:00
img = Image.open(
IMAGE_PATH + f"temp/{event.user_id}_{i}_update.png"
).filter(ImageFilter.BLUR)
2021-05-20 19:27:31 +08:00
result += image(b64=pic2b64(img))
2021-07-30 21:21:51 +08:00
if method in ["锐化效果", "7"]:
2021-05-20 19:27:31 +08:00
for i in range(index):
2021-07-30 21:21:51 +08:00
img = Image.open(
IMAGE_PATH + f"temp/{event.user_id}_{i}_update.png"
).filter(ImageFilter.EDGE_ENHANCE)
2021-05-20 19:27:31 +08:00
result += image(b64=pic2b64(img))
2021-07-30 21:21:51 +08:00
if method in ["高斯模糊", "8"]:
2021-05-20 19:27:31 +08:00
for i in range(index):
2021-07-30 21:21:51 +08:00
img = Image.open(
IMAGE_PATH + f"temp/{event.user_id}_{i}_update.png"
).filter(ImageFilter.GaussianBlur)
2021-05-20 19:27:31 +08:00
result += image(b64=pic2b64(img))
2021-07-30 21:21:51 +08:00
if method in ["边缘检测", "9"]:
2021-05-20 19:27:31 +08:00
for i in range(index):
2021-07-30 21:21:51 +08:00
img = Image.open(
IMAGE_PATH + f"temp/{event.user_id}_{i}_update.png"
).filter(ImageFilter.FIND_EDGES)
2021-05-20 19:27:31 +08:00
result += image(b64=pic2b64(img))
2021-07-30 21:21:51 +08:00
if method in ["底色替换", "10"]:
if x in ["蓝色", ""]:
2021-05-20 19:27:31 +08:00
lower = np.array([90, 70, 70])
upper = np.array([110, 255, 255])
2021-07-30 21:21:51 +08:00
if x in ["红色", ""]:
2021-05-20 19:27:31 +08:00
lower = np.array([0, 135, 135])
upper = np.array([180, 245, 230])
2021-07-30 21:21:51 +08:00
if y in ["蓝色", ""]:
2021-05-20 19:27:31 +08:00
color = (255, 0, 0)
2021-07-30 21:21:51 +08:00
if y in ["红色", ""]:
2021-05-20 19:27:31 +08:00
color = (0, 0, 255)
2021-07-30 21:21:51 +08:00
if y in ["白色", ""]:
2021-05-20 19:27:31 +08:00
color = (255, 255, 255)
2021-07-30 21:21:51 +08:00
if y in ["绿色", "绿"]:
2021-05-20 19:27:31 +08:00
color = (0, 255, 0)
2021-07-30 21:21:51 +08:00
if y in ["黄色", ""]:
2021-05-20 19:27:31 +08:00
color = (0, 255, 255)
for k in range(index):
2021-07-30 21:21:51 +08:00
img = cv2.imread(IMAGE_PATH + f"temp/{event.user_id}_{k}_update.png")
2021-05-20 19:27:31 +08:00
img = cv2.resize(img, None, fx=0.3, fy=0.3)
rows, cols, channels = img.shape
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, lower, upper)
# erode = cv2.erode(mask, None, iterations=1)
dilate = cv2.dilate(mask, None, iterations=1)
for i in range(rows):
for j in range(cols):
if dilate[i, j] == 255:
img[i, j] = color
2021-07-30 21:21:51 +08:00
cv2.imwrite(IMAGE_PATH + f"temp/{event.user_id}_{k}_ok_update.png", img)
2021-05-20 19:27:31 +08:00
for i in range(index):
2021-07-30 21:21:51 +08:00
result += image(f"{event.user_id}_{i}_ok_update.png", "temp")
2021-05-20 19:27:31 +08:00
if is_number(method):
method = method_list[int(method) - 1]
logger.info(
f"(USER {event.user_id}, GROUP"
2021-07-30 21:21:51 +08:00
f" {event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 使用{method}"
)
2021-05-20 19:27:31 +08:00
await update_img.finish(result, at_sender=True)