diff --git a/GenshinUID/genshinuid_abyss/__init__.py b/GenshinUID/genshinuid_abyss/__init__.py index 767d553a..630e80c9 100644 --- a/GenshinUID/genshinuid_abyss/__init__.py +++ b/GenshinUID/genshinuid_abyss/__init__.py @@ -3,6 +3,7 @@ import re from gsuid_core.sv import SV from gsuid_core.bot import Bot from gsuid_core.models import Event +from gsuid_core.message_models import Button from gsuid_core.utils.error_reply import UID_HINT from ..utils.convert import get_uid @@ -48,4 +49,8 @@ async def send_abyss_info(bot: Bot, ev: Event): await bot.logger.info('[查询深渊信息]深渊层数: {}'.format(floor)) im = await draw_abyss_img(user_id, uid, floor, schedule_type) - await bot.send(im) + a = Button('🔍查询深渊11', '查询深渊11') + b = Button('🔚查询上期深渊', '查询上期深渊') + c = Button('♾️深渊概览', '深渊概览') + d = Button('👾怪物阵容', '版本深渊') + await bot.send_option(im, [a, b, c, d]) diff --git a/GenshinUID/genshinuid_collection/__init__.py b/GenshinUID/genshinuid_collection/__init__.py index fe2af925..ab8a3be2 100644 --- a/GenshinUID/genshinuid_collection/__init__.py +++ b/GenshinUID/genshinuid_collection/__init__.py @@ -1,15 +1,35 @@ from gsuid_core.sv import SV from gsuid_core.bot import Bot from gsuid_core.models import Event +from gsuid_core.message_models import Button from gsuid_core.utils.error_reply import UID_HINT from ..utils.convert import get_uid +from .draw_new_collection_card import draw_explore from .draw_collection_card import draw_explora_img, draw_collection_img +sv_cp = SV('查询完成度') sv_sj = SV('查询收集') sv_ts = SV('查询探索') +@sv_cp.on_command(('查询完成度', 'wcd'), block=True) +async def send_cp_info(bot: Bot, ev: Event): + await bot.logger.info('开始执行[查询完成度信息]') + # user_id = ev.at if ev.at else ev.user_id + + # 获取uid + uid = await get_uid(bot, ev) + if uid is None: + return await bot.send(UID_HINT) + await bot.logger.info('[查询角色面板]uid: {}'.format(uid)) + + im = await draw_explore(uid) + a = Button('🔍查询探索', '查询探索') + b = Button('🔍查询收集', '查询收集') + await bot.send_option(im, [a, b]) + + @sv_sj.on_command(('查询收集', 'sj'), block=True) async def send_collection_info(bot: Bot, ev: Event): await bot.logger.info('开始执行[查询收集信息]') @@ -22,7 +42,9 @@ async def send_collection_info(bot: Bot, ev: Event): await bot.logger.info('[查询角色面板]uid: {}'.format(uid)) im = await draw_collection_img(user_id, uid) - await bot.send(im) + a = Button('🔍查询探索', '查询探索') + b = Button('🔍查询收集', '查询收集') + await bot.send_option(im, [a, b]) @sv_ts.on_command(('查询探索', 'ts'), block=True) @@ -37,4 +59,6 @@ async def send_explora_info(bot: Bot, ev: Event): await bot.logger.info('[查询角色面板]uid: {}'.format(uid)) im = await draw_explora_img(user_id, uid) - await bot.send(im) + a = Button('🔍查询探索', '查询探索') + b = Button('🔍查询收集', '查询收集') + await bot.send_option(im, [a, b]) diff --git a/GenshinUID/genshinuid_collection/draw_new_collection_card.py b/GenshinUID/genshinuid_collection/draw_new_collection_card.py index 53f1574b..296d826e 100644 --- a/GenshinUID/genshinuid_collection/draw_new_collection_card.py +++ b/GenshinUID/genshinuid_collection/draw_new_collection_card.py @@ -1,8 +1,17 @@ -from PIL import Image +from PIL import Image, ImageDraw +from gsuid_core.utils.image.convert import convert_img +from gsuid_core.utils.image.image_tools import crop_center_img from gsuid_core.utils.download_resource.download_image import get_image from ..utils.resource.RESOURCE_PATH import ICON_PATH +from ..utils.image.image_tools import shift_image_hue from .draw_collection_card import TEXT_PATH, get_base_data +from ..utils.fonts.genshin_fonts import ( + gs_font_15, + gs_font_20, + gs_font_24, + gs_font_32, +) async def draw_explore(uid: str): @@ -12,14 +21,62 @@ async def draw_explore(uid: str): ): return raw_data - worlds = raw_data['world_explorations'] - for world in worlds: - area_bg = ( - Image.open(TEXT_PATH / 'area_bg') - .resize((216, 216)) - .convert('RGBA') - ) - icon = await get_image(world['icon'], ICON_PATH) - # percent = world['exploration_percentage'] + r = 20 + half_white = (255, 255, 255, 120) + white = (255, 255, 255) + black = (2, 2, 2) - area_bg.paste(icon, (27, 27), icon) + worlds = raw_data['world_explorations'] + + image = crop_center_img(Image.open(TEXT_PATH / 'bg.jpg'), 1400, 950) + + for index, world in enumerate(worlds): + area_bg = Image.open(TEXT_PATH / 'area_bg.png') + area_bg = await shift_image_hue(area_bg, 30) + icon = await get_image(world['icon'], ICON_PATH) + icon = icon.resize((150, 150)).convert('RGBA') + + percent = world['exploration_percentage'] + name = world['name'] + if '·' in name: + name = name.split('·')[-1] + rank = f'等阶{world["level"]}' + + completion = f'探索完成度: {percent / 10}%' + + area_bg.paste(icon, (75, 36), icon) + + area_draw = ImageDraw.Draw(area_bg) + + # 标题 + area_draw.text((150, 216), name, white, gs_font_32, 'mm') + + # 等阶 + area_draw.rounded_rectangle((98, 240, 201, 270), r, (137, 14, 14)) + area_draw.text((150, 255), rank, white, gs_font_24, 'mm') + + # 进度条 + lenth = percent * 182 / 1000 + area_draw.rounded_rectangle((59, 283, 241, 295), r, half_white) + area_draw.rounded_rectangle((59, 283, 59 + lenth, 295), r, white) + area_draw.text((150, 320), completion, white, gs_font_20, 'mm') + + # 副等阶,如果有的话 + if world['offerings']: + odata = world['offerings'][0] + oicon = await get_image(odata['icon'], ICON_PATH) + oicon = oicon.resize((38, 38)).convert('RGBA') + orank = f"等阶{odata['level']}" + + area_draw.rounded_rectangle((59, 340, 241, 387), r, half_white) + area_bg.paste(oicon, (63, 343), oicon) + area_draw.text((107, 352), odata['name'], black, gs_font_20, 'lm') + area_draw.rounded_rectangle((107, 364, 173, 384), r, (137, 14, 14)) + area_draw.text((140, 374), orank, white, gs_font_15, 'mm') + + image.paste( + area_bg, + (100 + 240 * (index % 5), 25 + 450 * (index // 5)), + area_bg, + ) + return await convert_img(image) diff --git a/GenshinUID/genshinuid_collection/texture2D/bg.jpg b/GenshinUID/genshinuid_collection/texture2D/bg.jpg new file mode 100644 index 00000000..693fe83c Binary files /dev/null and b/GenshinUID/genshinuid_collection/texture2D/bg.jpg differ diff --git a/GenshinUID/genshinuid_enka/__init__.py b/GenshinUID/genshinuid_enka/__init__.py index cfc0d4ff..0379d97f 100644 --- a/GenshinUID/genshinuid_enka/__init__.py +++ b/GenshinUID/genshinuid_enka/__init__.py @@ -8,6 +8,7 @@ from gsuid_core.sv import SV from gsuid_core.bot import Bot from gsuid_core.models import Event from gsuid_core.logger import logger +from gsuid_core.message_models import Button from gsuid_core.utils.error_reply import UID_HINT from .to_data import switch_api @@ -50,7 +51,14 @@ async def sned_rank_pic(bot: Bot, ev: Event): if uid is None: return await bot.send(UID_HINT) logger.info(f'[排名列表]uid: {uid}') - await bot.send(await draw_rank_img(ev.user_id, uid)) + im = await draw_rank_img(ev.user_id, uid) + await bot.send_option( + im, + [ + Button('♾️角色排名公子', '角色排名公子'), + Button('♾️圣遗物双爆排名', '圣遗物排名双爆'), + ], + ) @sv_akasha.on_prefix('角色排名') @@ -68,7 +76,16 @@ async def sned_arti_rank_pic(bot: Bot, ev: Event): # 获取排序名 msg = ''.join(re.findall('[\u4e00-\u9fa5 ]', ev.text)) logger.info(f'[圣遗物排名]排序: {msg}') - await bot.send(await draw_arti_rank_img(msg)) + im = await draw_arti_rank_img(msg) + await bot.send_option( + im, + [ + Button('♾️双爆排名', '圣遗物排名双爆'), + Button('♾️暴击率排名', '圣遗物排名暴击率'), + Button('♾️元素精通排名', '圣遗物排名元素精通'), + Button('♾️暴击伤害排名', '圣遗物排名暴击伤害'), + ], + ) @sv_enka_admin.on_fullmatch('刷新全部圣遗物仓库') @@ -108,7 +125,16 @@ async def sned_aritifacts_list(bot: Bot, ev: Event): else: num = 1 - await bot.send(await draw_lib(ev.user_id, uid, num)) + im = await draw_lib(ev.user_id, uid, num) + await bot.send_option( + im, + [ + Button('♾️双爆排名', '圣遗物排名双爆'), + Button('♾️暴击率排名', '圣遗物排名暴击率'), + Button('♾️元素精通排名', '圣遗物排名元素精通'), + Button('♾️暴击伤害排名', '圣遗物排名暴击伤害'), + ], + ) @sv_get_original_pic.on_fullmatch(('原图')) @@ -128,7 +154,8 @@ async def send_change_api_info(bot: Bot, ev: Event): @sv_get_enka.on_prefix('查询') async def send_char_info(bot: Bot, ev: Event): - im = await _get_char_info(bot, ev, ev.text) + name = ev.text.strip() + im = await _get_char_info(bot, ev, name) if isinstance(im, str): await bot.send(im) elif isinstance(im, Tuple): @@ -136,7 +163,15 @@ async def send_char_info(bot: Bot, ev: Event): img = await convert_img(im[0]) else: img = im[0] - await bot.send(img) + await bot.send_option( + img, + [ + Button('🔄更换武器', f'查询{name}换'), + Button('⏫提高命座', f'查询六命{name}'), + Button('*️⃣保存面板', f'保存面板{name}为 '), + Button('🔀对比面板', f'对比面板 {name} '), + ], + ) if im[1]: with open(TEMP_PATH / f'{ev.msg_id}.jpg', 'wb') as f: f.write(im[1]) @@ -162,8 +197,10 @@ async def _get_char_info(bot: Bot, ev: Event, text: str): return im -@sv_get_enka.on_prefix('对比面板') +@sv_get_enka.on_command('对比面板') async def contrast_char_info(bot: Bot, ev: Event): + if not ev.text.strip(): + return await bot.send('参考格式: 对比面板 公子 公子换可莉圣遗物') contrast_list = ev.text.strip().split(' ') if len(contrast_list) <= 1: return await bot.send('输入格式错误...参考格式: 对比面板 公子 公子换可莉圣遗物') @@ -194,8 +231,10 @@ async def contrast_char_info(bot: Bot, ev: Event): await bot.send(await convert_img(base_img)) -@sv_get_enka.on_prefix('保存面板') +@sv_get_enka.on_command('保存面板') async def save_char_info(bot: Bot, ev: Event): + if not ev.text.strip(): + return await bot.send('后面需要跟自定义的保存名字\n例如:保存面板公子为核爆公子') save_list = ev.text.strip().split('为') if len(save_list) <= 1: return await bot.send('输入格式错误...参考格式: 保存面板公子为核爆公子') @@ -241,10 +280,16 @@ async def save_char_info(bot: Bot, ev: Event): path = SELF_PATH / f'{save_name}.json' async with aiofiles.open(path, 'wb') as file: await file.write(json.dumps(char_data).encode('utf-8')) - return await bot.send(f'保存成功!你可以使用[查询{save_name}]调用该面板!') + return await bot.send_option( + f'保存成功!你可以使用[查询{save_name}]调用该面板!', + [ + Button(f'✅查询{save_name}', f'查询{save_name}'), + Button('💖刷新面板', '刷新面板'), + ], + ) -@sv_get_enka.on_command('强制刷新') +@sv_get_enka.on_command(('强制刷新', '刷新面板')) async def send_card_info(bot: Bot, ev: Event): uid = await get_uid(bot, ev) if uid is None: @@ -254,7 +299,13 @@ async def send_card_info(bot: Bot, ev: Event): logger.info(f'UID{uid}获取角色数据成功!') if isinstance(im, Tuple): - await bot.send_option(im[0], [f'查询{i["avatarName"]}' for i in im[1]]) + buttons = [ + Button(f'✅查询{i["avatarName"]}', f'查询{i["avatarName"]}') + for i in im[1] + ] + buttons.append(Button('📦圣遗物仓库', '圣遗物仓库')) + buttons.append(Button('💖排名列表', '排名列表')) + await bot.send_option(im[0], buttons) else: await bot.send(im) diff --git a/GenshinUID/genshinuid_etcimg/__init__.py b/GenshinUID/genshinuid_etcimg/__init__.py index 21142907..361d97a2 100644 --- a/GenshinUID/genshinuid_etcimg/__init__.py +++ b/GenshinUID/genshinuid_etcimg/__init__.py @@ -3,6 +3,7 @@ from pathlib import Path from gsuid_core.sv import SV from gsuid_core.bot import Bot from gsuid_core.models import Event +from gsuid_core.message_models import Button from ..version import Genshin_version from ..utils.image.convert import convert_img @@ -28,7 +29,9 @@ async def send_primogems_data(bot: Bot, ev: Event): primogems_img = PRIMOGEMS_DATA_PATH / img await bot.logger.info('[图片][版本规划]访问图片: {}'.format(img)) primogems_img = await convert_img(primogems_img) - await bot.send(primogems_img) + a = Button('📄版本规划4.3', '版本规划4.3') + b = Button('🔔今日材料', '今日材料') + await bot.send_option(primogems_img, [a, b]) @sv_etc_img.on_fullmatch(('伤害乘区', '血量表', '抗性表', '血量排行')) @@ -36,6 +39,10 @@ async def send_img_data(bot: Bot, ev: Event): await bot.logger.info('开始执行[图片][杂图]') img = IMG_PATH / f'{ev.command}.jpg' if img.exists(): - await bot.send(await convert_img(img)) + a = Button('👾怪物血量表', '血量表') + b = Button('👾怪物抗性表', '抗性表') + c = Button('👾怪物血量排行', '血量排行') + d = Button('🤖伤害乘区', '伤害乘区') + await bot.send_option(await convert_img(img), [a, b, c, d]) else: return diff --git a/GenshinUID/genshinuid_eventlist/__init__.py b/GenshinUID/genshinuid_eventlist/__init__.py index 5c22306b..78fa171f 100644 --- a/GenshinUID/genshinuid_eventlist/__init__.py +++ b/GenshinUID/genshinuid_eventlist/__init__.py @@ -2,6 +2,7 @@ from gsuid_core.sv import SV from gsuid_core.bot import Bot from gsuid_core.models import Event from gsuid_core.aps import scheduler +from gsuid_core.message_models import Button from ..utils.image.convert import convert_img from .draw_event_img import get_event_img, get_all_event_img @@ -17,10 +18,14 @@ async def draw_event(): @sv_event_list.on_fullmatch('活动列表') async def send_events(bot: Bot, ev: Event): img = await get_event_img('EVENT') - await bot.send(await convert_img(img)) + a = Button('📢原神公告列表', '原神公告') + b = Button('💞卡池列表', '卡池列表') + await bot.send_option(await convert_img(img), [a, b]) @sv_event_list.on_fullmatch('卡池列表') async def send_gachas(bot: Bot, ev: Event): img = await get_event_img('GACHA') - await bot.send(await convert_img(img)) + a = Button('📢原神公告列表', '原神公告') + b = Button('💝活动列表', '活动列表') + await bot.send_option(await convert_img(img), [a, b]) diff --git a/GenshinUID/genshinuid_gachalog/__init__.py b/GenshinUID/genshinuid_gachalog/__init__.py index f493f58f..fc36733f 100644 --- a/GenshinUID/genshinuid_gachalog/__init__.py +++ b/GenshinUID/genshinuid_gachalog/__init__.py @@ -1,6 +1,7 @@ from gsuid_core.sv import SV from gsuid_core.bot import Bot from gsuid_core.models import Event +from gsuid_core.message_models import Button from gsuid_core.segment import MessageSegment from gsuid_core.utils.error_reply import UID_HINT from gsuid_core.utils.database.models import GsBind @@ -45,7 +46,10 @@ async def send_gacha_log_card_info(bot: Bot, ev: Event): if uid is None: return await bot.send(UID_HINT) im = await draw_gachalogs_img(uid, user_id) - await bot.send(im) + a = Button('🔁刷新抽卡记录', '刷新抽卡记录') + b = Button('🔜导出抽卡记录至提瓦特小助手', '导出抽卡记录到小助手') + c = Button('🔙从提瓦特小助手导入抽卡记录', '从小助手导入抽卡记录') + await bot.send_option(im, [[a], [b], [c]]) @sv_refresh_gacha_log.on_fullmatch(('刷新抽卡记录', '强制刷新抽卡记录')) @@ -60,7 +64,7 @@ async def send_refresh_gacha_info(bot: Bot, ev: Event): is_force = True await bot.send(f'UID{uid}开始执行[刷新抽卡记录],需要一定时间...请勿重复触发!') im = await save_gachalogs(uid, None, is_force) - await bot.send(im) + await bot.send_option(im, [Button('🃏抽卡记录', '抽卡记录')]) @sv_export_gacha_log.on_fullmatch(('导出抽卡记录')) diff --git a/GenshinUID/genshinuid_gcg/__init__.py b/GenshinUID/genshinuid_gcg/__init__.py index f0710fbb..cb0400b8 100644 --- a/GenshinUID/genshinuid_gcg/__init__.py +++ b/GenshinUID/genshinuid_gcg/__init__.py @@ -1,6 +1,7 @@ from gsuid_core.sv import SV from gsuid_core.bot import Bot from gsuid_core.models import Event +from gsuid_core.message_models import Button from gsuid_core.utils.error_reply import UID_HINT from ..utils.convert import get_uid @@ -10,7 +11,7 @@ from .draw_gcginfo import draw_gcg_info sv_gcg = SV('查询七圣') -@sv_gcg.on_command(('七圣召唤', 'qszh')) +@sv_gcg.on_command(('七圣召唤', 'qszh', '七圣数据总览')) async def send_gcg_pic(bot: Bot, ev: Event): uid = await get_uid(bot, ev) if uid is None: @@ -18,7 +19,7 @@ async def send_gcg_pic(bot: Bot, ev: Event): await bot.logger.info('[七圣召唤]uid: {}'.format(uid)) im = await draw_gcg_info(uid) - await bot.send(im) + await bot.send_option(im, [Button('✅我的卡组', '我的卡组')]) @sv_gcg.on_command(('我的卡组', '我的牌组')) @@ -34,4 +35,4 @@ async def send_deck_pic(bot: Bot, ev: Event): else: return bot.send('请输入正确的序号, 例如我的卡组1...') im = await draw_deck_img(ev.user_id, uid, deck_id) - await bot.send(im) + await bot.send_option(im, [Button('✅七圣数据总览', '七圣召唤')]) diff --git a/GenshinUID/genshinuid_guide/__init__.py b/GenshinUID/genshinuid_guide/__init__.py index cfcff039..e99c101a 100644 --- a/GenshinUID/genshinuid_guide/__init__.py +++ b/GenshinUID/genshinuid_guide/__init__.py @@ -4,6 +4,7 @@ from typing import List from gsuid_core.sv import SV from gsuid_core.bot import Bot from gsuid_core.models import Event +from gsuid_core.message_models import Button from gsuid_core.segment import MessageSegment from .get_guide import get_gs_guide @@ -25,7 +26,7 @@ async def send_guide_pic(bot: Bot, ev: Event): if im: await bot.logger.info('获得{}攻略成功!'.format(ev.text)) - await bot.send(im) + await bot.send_option(im, [Button(f'🎴参考面板{ev.text}', '参考面板{ev.text}')]) else: await bot.logger.warning('未找到{}攻略图片'.format(ev.text)) @@ -40,7 +41,7 @@ async def send_bluekun_pic(bot: Bot, ev: Event): if img.exists(): img = await convert_img(img) await bot.logger.info('获得{}参考面板图片成功!'.format(name)) - await bot.send(img) + await bot.send_option(img, [Button(f'🎴{name}攻略', f'{name}攻略')]) else: await bot.logger.warning('未找到{}参考面板图片'.format(name)) diff --git a/GenshinUID/genshinuid_wikitext/get_cost_pic.py b/GenshinUID/genshinuid_wikitext/get_cost_pic.py index 4fc86cc9..0efc2e30 100644 --- a/GenshinUID/genshinuid_wikitext/get_cost_pic.py +++ b/GenshinUID/genshinuid_wikitext/get_cost_pic.py @@ -16,6 +16,12 @@ from ..utils.get_assets import get_assets_from_ambr from ..utils.map.name_covert import name_to_avatar_id from ..utils.image.convert import str_lenth, convert_img from ..utils.resource.RESOURCE_PATH import CHAR_PATH, WIKI_COST_CHAR_PATH +from ..utils.image.image_tools import ( + get_star_png, + get_simple_bg, + get_unknown_png, + draw_pic_with_ring, +) from ..utils.fonts.genshin_fonts import ( gs_font_24, gs_font_26, @@ -23,12 +29,6 @@ from ..utils.fonts.genshin_fonts import ( gs_font_36, gs_font_44, ) -from ..utils.image.image_tools import ( - get_star_png, - get_simple_bg, - get_unknown_png, - draw_pic_with_ring, -) async def get_char_cost_wiki_img(name: str) -> Union[str, bytes]: @@ -93,6 +93,7 @@ async def draw_single_cost(title: str, data: Dict) -> Tuple[Image.Image, str]: y = 165 * (index // 5) tent_x = 34 tent_y = 23 + cost_pic = cost_pic.convert('RGBA') img.paste(cost_pic, (67 + tent_x + t, 61 + tent_y + y), cost_pic) val = str(data[cost_name]) img_draw.text( diff --git a/GenshinUID/utils/image/image_tools.py b/GenshinUID/utils/image/image_tools.py index 722af22d..c7230fe7 100644 --- a/GenshinUID/utils/image/image_tools.py +++ b/GenshinUID/utils/image/image_tools.py @@ -31,6 +31,24 @@ else: bg_path = NM_BG_PATH +async def shift_image_hue(img: Image.Image, angle: float = 30) -> Image.Image: + alpha = img.getchannel('A') + img = img.convert('HSV') + + pixels = img.load() + hue_shift = angle + + for y in range(img.height): + for x in range(img.width): + h, s, v = pixels[x, y] + h = (h + hue_shift) % 360 + pixels[x, y] = (h, s, v) + + img = img.convert('RGBA') + img.putalpha(alpha) + return img + + async def _get(url: str): async with httpx.AsyncClient(timeout=None) as client: resp = await client.get(url=url) @@ -38,9 +56,9 @@ async def _get(url: str): async def get_pic(url, size: Optional[Tuple[int, int]] = None) -> Image.Image: - """ + ''' 从网络获取图片, 格式化为RGBA格式的指定尺寸 - """ + ''' async with httpx.AsyncClient(timeout=None) as client: resp = await client.get(url=url) if resp.status_code != 200: @@ -48,7 +66,7 @@ async def get_pic(url, size: Optional[Tuple[int, int]] = None) -> Image.Image: size = (960, 600) return Image.new('RGBA', size) pic = Image.open(BytesIO(resp.read())) - pic = pic.convert("RGBA") + pic = pic.convert('RGBA') if size is not None: pic = pic.resize(size, Image.Resampling.LANCZOS) return pic @@ -74,11 +92,11 @@ def draw_text_by_line( center=False, line_space: Optional[float] = None, ): - """ + ''' 在图片上写长段文字, 自动换行 max_length单行最大长度, 单位像素 line_space 行间距, 单位像素, 默认是字体高度的0.3倍 - """ + ''' x, y = pos _, h = get_size(font, 'X') if line_space is None: @@ -86,7 +104,7 @@ def draw_text_by_line( else: y_add = math.ceil(h + line_space) draw = ImageDraw.Draw(img) - row = "" # 存储本行文字 + row = '' # 存储本行文字 length = 0 # 记录本行长度 for character in text: # 获取当前字符的宽度 @@ -100,10 +118,10 @@ def draw_text_by_line( fw, _ = get_size(font, row) x = math.ceil((img.size[0] - fw) / 2) draw.text((x, y), row, font=font, fill=fill) - row = "" + row = '' length = 0 y += y_add - if row != "": + if row != '': if center: fw, _ = get_size(font, row) x = math.ceil((img.size[0] - fw) / 2) @@ -111,32 +129,32 @@ def draw_text_by_line( def easy_paste( - im: Image.Image, im_paste: Image.Image, pos=(0, 0), direction="lt" + im: Image.Image, im_paste: Image.Image, pos=(0, 0), direction='lt' ): - """ + ''' inplace method 快速粘贴, 自动获取被粘贴图像的坐标。 pos应当是粘贴点坐标,direction指定粘贴点方位,例如lt为左上 - """ + ''' x, y = pos size_x, size_y = im_paste.size - if "d" in direction: + if 'd' in direction: y = y - size_y - if "r" in direction: + if 'r' in direction: x = x - size_x - if "c" in direction: + if 'c' in direction: x = x - int(0.5 * size_x) y = y - int(0.5 * size_y) im.paste(im_paste, (x, y, x + size_x, y + size_y), im_paste) def easy_alpha_composite( - im: Image.Image, im_paste: Image.Image, pos=(0, 0), direction="lt" + im: Image.Image, im_paste: Image.Image, pos=(0, 0), direction='lt' ) -> Image.Image: ''' 透明图像快速粘贴 ''' - base = Image.new("RGBA", im.size) + base = Image.new('RGBA', im.size) easy_paste(base, im_paste, pos, direction) base = Image.alpha_composite(im, base) return base @@ -358,7 +376,7 @@ class CustomizeImage: @staticmethod def get_dominant_color(pil_img: Image.Image) -> Tuple[int, int, int]: img = pil_img.copy() - img = img.convert("RGBA") + img = img.convert('RGBA') img = img.resize((1, 1), resample=0) dominant_color = img.getpixel((0, 0)) return dominant_color