mirror of
https://github.com/xuthus83/LittlePaimon.git
synced 2024-10-21 16:27:15 +08:00
优化图片生成速度
This commit is contained in:
parent
d92913772c
commit
cc92c655a7
@ -2,7 +2,7 @@ import datetime
|
||||
import os
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
from pathlib import Path
|
||||
from utils import aiorequests
|
||||
from utils.message_util import MessageBuild
|
||||
from utils.file_handler import load_image
|
||||
@ -111,27 +111,32 @@ async def draw_abyss_card(data, uid, floor_num):
|
||||
top_img.alpha_composite(role_img, (width, 165))
|
||||
width += 150
|
||||
defeat_rank = data['defeat_rank'][0]
|
||||
defeat_rank_img = await aiorequests.get_img(url=defeat_rank['avatar_icon'], size=(60, 60), mode='RGBA')
|
||||
avatar_img = Path() / 'data' / 'LittlePaimon' / 'res' / 'avatar_side' / defeat_rank['avatar_icon'].split('/')[-1]
|
||||
defeat_rank_img = await aiorequests.get_img(url=defeat_rank['avatar_icon'], size=(60, 60), mode='RGBA', save_path=avatar_img)
|
||||
top_draw.text((160, 343), str(defeat_rank['value']), font=get_font(21), fill='white')
|
||||
top_img.alpha_composite(defeat_rank_img, (280, 320))
|
||||
|
||||
damage_rank = data['damage_rank'][0]
|
||||
damage_rank_img = await aiorequests.get_img(url=damage_rank['avatar_icon'], size=(60, 60), mode='RGBA')
|
||||
avatar_img = Path() / 'data' / 'LittlePaimon' / 'res' / 'avatar_side' / damage_rank['avatar_icon'].split('/')[-1]
|
||||
damage_rank_img = await aiorequests.get_img(url=damage_rank['avatar_icon'], size=(60, 60), mode='RGBA', save_path=avatar_img)
|
||||
top_draw.text((495, 343), str(damage_rank['value']), font=get_font(21), fill='white')
|
||||
top_img.alpha_composite(damage_rank_img, (590, 320))
|
||||
|
||||
take_damage_rank = data['take_damage_rank'][0]
|
||||
take_damage_rank_img = await aiorequests.get_img(url=take_damage_rank['avatar_icon'], size=(60, 60), mode='RGBA')
|
||||
avatar_img = Path() / 'data' / 'LittlePaimon' / 'res' / 'avatar_side' / take_damage_rank['avatar_icon'].split('/')[-1]
|
||||
take_damage_rank_img = await aiorequests.get_img(url=take_damage_rank['avatar_icon'], size=(60, 60), mode='RGBA', save_path=avatar_img)
|
||||
top_draw.text((180, 389), str(take_damage_rank['value']), font=get_font(21), fill='white')
|
||||
top_img.alpha_composite(take_damage_rank_img, (280, 365))
|
||||
|
||||
energy_skill_rank = data['energy_skill_rank'][0]
|
||||
energy_skill_rank_img = await aiorequests.get_img(url=energy_skill_rank['avatar_icon'], size=(60, 60), mode='RGBA')
|
||||
avatar_img = Path() / 'data' / 'LittlePaimon' / 'res' / 'avatar_side' / energy_skill_rank['avatar_icon'].split('/')[-1]
|
||||
energy_skill_rank_img = await aiorequests.get_img(url=energy_skill_rank['avatar_icon'], size=(60, 60), mode='RGBA', save_path=avatar_img)
|
||||
top_draw.text((530, 389), str(energy_skill_rank['value']), font=get_font(21), fill='white')
|
||||
top_img.alpha_composite(energy_skill_rank_img, (590, 365))
|
||||
|
||||
normal_skill_rank = data['normal_skill_rank'][0]
|
||||
normal_skill_rank_img = await aiorequests.get_img(url=normal_skill_rank['avatar_icon'], size=(60, 60), mode='RGBA')
|
||||
avatar_img = Path() / 'data' / 'LittlePaimon' / 'res' / 'avatar_side' / normal_skill_rank['avatar_icon'].split('/')[-1]
|
||||
normal_skill_rank_img = await aiorequests.get_img(url=normal_skill_rank['avatar_icon'], size=(60, 60), mode='RGBA', save_path=avatar_img)
|
||||
top_draw.text((195, 435), str(normal_skill_rank['value']), font=get_font(21), fill='white')
|
||||
top_img.alpha_composite(normal_skill_rank_img, (280, 410))
|
||||
|
||||
|
@ -5,6 +5,7 @@ import random
|
||||
import matplotlib.pyplot as plt
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
from pathlib import Path
|
||||
from utils import aiorequests
|
||||
from utils.message_util import MessageBuild
|
||||
from utils.file_handler import load_image
|
||||
@ -121,7 +122,8 @@ async def draw_daily_note_card(data, uid):
|
||||
exp = data['expeditions']
|
||||
i = 0
|
||||
for role in exp:
|
||||
role_avatar = await aiorequests.get_img(url=role['avatar_side_icon'], size=(135, 135), mode='RGBA')
|
||||
role_avatar = Path() / 'data' / 'LittlePaimon' / 'res' / 'avatar_side' / role['avatar_side_icon'].split('/')[-1]
|
||||
role_avatar = await aiorequests.get_img(url=role['avatar_side_icon'], size=(135, 135), mode='RGBA', save_path=role_avatar)
|
||||
bg_img.alpha_composite(role_avatar, (i * 200 + 168, 1537))
|
||||
bg_img.alpha_composite(await draw_ring(1 - int(role['remained_time']) / 72000), (i * 201 + 101, 1490))
|
||||
if role['status'] == 'Ongoing':
|
||||
@ -147,7 +149,6 @@ async def draw_daily_note_card(data, uid):
|
||||
bg_draw.text((1408, 1588), last_finish_str, fill="#5680d2",
|
||||
font=get_font(60, '优设标题黑.ttf'))
|
||||
|
||||
|
||||
role_img = load_image(os.path.join(res_path, 'emoticons', random.choice(os.listdir(os.path.join(res_path, 'emoticons')))), size=3.5, mode='RGBA')
|
||||
bg_img.alpha_composite(role_img, (1220, 200))
|
||||
now = datetime.datetime.now().strftime('%m月%d日%H:%M')
|
||||
|
@ -3,6 +3,7 @@ import os
|
||||
import random
|
||||
import re
|
||||
|
||||
from pathlib import Path
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
from utils import aiorequests
|
||||
@ -11,6 +12,18 @@ from utils.file_handler import load_image
|
||||
|
||||
res_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'res')
|
||||
|
||||
b = load_image(os.path.join(res_path, 'player_card', '角色卡底部.png'))
|
||||
b_c = load_image(os.path.join(res_path, 'player_card', 'chara_botton.png'))
|
||||
fetter = []
|
||||
for i in range(0, 11):
|
||||
fetter.append(load_image(os.path.join(res_path, 'player_card', f'好感度{i}.png')))
|
||||
weapon_bg = []
|
||||
for i in range(1, 6):
|
||||
weapon_bg.append(load_image(os.path.join(res_path, 'player_card', f'{i}星武器.png')))
|
||||
constellation = []
|
||||
for i in range(0, 7):
|
||||
constellation.append(load_image(os.path.join(res_path, 'player_card', f'命之座{i}.png')))
|
||||
|
||||
|
||||
def get_font(size):
|
||||
return ImageFont.truetype(os.path.join(res_path, 'msyh.ttc'), size)
|
||||
@ -31,22 +44,18 @@ async def get_chara_card(data):
|
||||
chara_card = Image.new("RGBA", (226, 313), (255, 255, 255, 255))
|
||||
chara_img = load_image(os.path.join(res_path, 'role_card', f'{data["id"]}.png'))
|
||||
chara_card.alpha_composite(chara_img, (0, 0))
|
||||
b = load_image(os.path.join(res_path, 'player_card', 'chara_botton.png'))
|
||||
chara_card.alpha_composite(b, (0, 236))
|
||||
chara_card.alpha_composite(b_c, (0, 236))
|
||||
# 命座
|
||||
if data['name'] != '埃洛伊':
|
||||
actived_constellation_num = load_image(
|
||||
os.path.join(res_path, 'player_card', f'命之座{data["actived_constellation_num"]}.png'))
|
||||
chara_card.alpha_composite(actived_constellation_num, (155, 0))
|
||||
chara_card.alpha_composite(constellation[data["actived_constellation_num"]], (155, 0))
|
||||
# 好感度
|
||||
if data['name'] != '旅行者':
|
||||
fetter = load_image(os.path.join(res_path, 'player_card', f'好感度{data["fetter"]}.png'))
|
||||
chara_card.alpha_composite(fetter, (155, 166))
|
||||
chara_card.alpha_composite(fetter[data["fetter"]], (155, 166))
|
||||
# 武器背景
|
||||
weapon_bg = load_image(os.path.join(res_path, 'player_card', f'{data["weapon"]["rarity"]}星武器.png'))
|
||||
chara_card.alpha_composite(weapon_bg, (0, 227))
|
||||
chara_card.alpha_composite(weapon_bg[data["weapon"]["rarity"] - 1], (0, 227))
|
||||
# 武器图标
|
||||
weapon_icon = await aiorequests.get_img(url=data['weapon']['icon'], size=(63, 63), mode='RGBA')
|
||||
weapon_icon = Path() / 'data' / 'LittlePaimon' / 'res' / 'weapon' / data['weapon']['icon'].split('/')[-1]
|
||||
weapon_icon = await aiorequests.get_img(url=data['weapon']['icon'], size=(63, 63), mode='RGBA', save_path=weapon_icon)
|
||||
chara_card.alpha_composite(weapon_icon, (0, 230))
|
||||
# 等级信息
|
||||
chara_draw = ImageDraw.Draw(chara_card)
|
||||
@ -252,7 +261,6 @@ async def get_chara_card_long(data):
|
||||
chara_card = Image.new("RGBA", (226, 382), (255, 255, 255, 255))
|
||||
chara_img = load_image(os.path.join(res_path, 'role_card', f'{data["id"]}.png'))
|
||||
chara_card.alpha_composite(chara_img, (0, 0))
|
||||
b = load_image(os.path.join(res_path, 'player_card', '角色卡底部.png'))
|
||||
chara_card.alpha_composite(b, (0, 282))
|
||||
# 命座
|
||||
if data['name'] != '埃洛伊':
|
||||
@ -261,12 +269,11 @@ async def get_chara_card_long(data):
|
||||
chara_card.alpha_composite(actived_constellation_num, (155, 0))
|
||||
# 好感度
|
||||
if data['name'] != '旅行者':
|
||||
fetter = load_image(os.path.join(res_path, 'player_card', f'好感度{data["fetter"]}.png'))
|
||||
chara_card.alpha_composite(fetter, (155, 166))
|
||||
chara_card.alpha_composite(fetter[data['fetter']], (155, 166))
|
||||
# 武器背景
|
||||
weapon_bg = load_image(os.path.join(res_path, 'player_card', f'{data["weapon"]["rarity"]}星武器.png'))
|
||||
chara_card.alpha_composite(weapon_bg, (3, 288))
|
||||
weapon_icon = await aiorequests.get_img(url=data['weapon']['icon'], size=(62, 62), mode='RGBA')
|
||||
chara_card.alpha_composite(weapon_bg[data["weapon"]["rarity"] - 1], (3, 288))
|
||||
weapon_icon = Path() / 'data' / 'LittlePaimon' / 'res' / 'weapon' / data['weapon']['icon'].split('/')[-1]
|
||||
weapon_icon = await aiorequests.get_img(url=data['weapon']['icon'], size=(62, 62), mode='RGBA', save_path=weapon_icon)
|
||||
chara_card.alpha_composite(weapon_icon, (3, 291))
|
||||
# 等级信息
|
||||
chara_draw = ImageDraw.Draw(chara_card)
|
||||
@ -330,7 +337,8 @@ shadow = load_image(os.path.join(res_path, 'other', 'shadow.png'))
|
||||
|
||||
async def draw_reli_icon(data):
|
||||
base_icon = load_image(os.path.join(res_path, 'other', f'star{data["rarity"]}.png'), size=(80, 80))
|
||||
icon = await aiorequests.get_img(url=data["icon"], size=(80, 80), mode='RGBA')
|
||||
icon = Path() / 'data' / 'LittlePaimon' / 'res' / 'reli' / data['icon'].split('/')[-1]
|
||||
icon = await aiorequests.get_img(url=data["icon"], size=(80, 80), mode='RGBA', save_path=icon)
|
||||
base_icon.alpha_composite(icon, (0, 0))
|
||||
base_icon.alpha_composite(shadow, (40, 60))
|
||||
base_icon_draw = ImageDraw.Draw(base_icon)
|
||||
@ -340,7 +348,8 @@ async def draw_reli_icon(data):
|
||||
|
||||
async def draw_const_skill_icon(data, name):
|
||||
base_icon = load_image(os.path.join(res_path, 'other', '命座.png'), size=(65, 65))
|
||||
icon = await aiorequests.get_img(url=data["icon"], size=(65, 65), mode='RGBA')
|
||||
icon = Path() / 'data' / 'LittlePaimon' / 'res' / 'skill' / data['icon'].split('/')[-1]
|
||||
icon = await aiorequests.get_img(url=data["icon"], size=(65, 65), mode='RGBA', save_path=icon)
|
||||
base_icon.alpha_composite(icon, (0, 0))
|
||||
if 'is_actived' in data and not data['is_actived']:
|
||||
unlock_icon = load_image(os.path.join(res_path, 'other', '命座未解锁.png'), size=(65, 65))
|
||||
@ -412,7 +421,8 @@ async def draw_chara_card(data, skill_data, chara_name, uid):
|
||||
|
||||
# 武器
|
||||
weapon_bg = load_image(os.path.join(res_path, 'other', f'star{character["weapon"]["rarity"]}.png'), size=(100, 100))
|
||||
weapon_icon = await aiorequests.get_img(url=character['weapon']['icon'], size=(100, 100), mode='RGBA')
|
||||
weapon_icon = Path() / 'data' / 'LittlePaimon' / 'res' / 'weapon' / character['weapon']['icon'].split('/')[-1]
|
||||
weapon_icon = await aiorequests.get_img(url=character['weapon']['icon'], size=(100, 100), mode='RGBA', save_path=weapon_icon)
|
||||
bg_img.alpha_composite(weapon_bg, (293, 175))
|
||||
bg_img.alpha_composite(weapon_icon, (293, 175))
|
||||
bg_img.alpha_composite(shadow.resize((50, 25)), (344, 250))
|
||||
|
@ -66,7 +66,7 @@ async def get_img(url: str,
|
||||
params: Optional[Dict[str, Any]] = None,
|
||||
timeout: Optional[int] = 20,
|
||||
save_path: Optional[Union[str, Path]] = None,
|
||||
size: Optional[Tuple[int, int]] = None,
|
||||
size: Optional[Union[Tuple[int, int], float]] = None,
|
||||
mode: Optional[str] = None,
|
||||
crop: Optional[Tuple[int, int, int, int]] = None,
|
||||
**kwargs) -> Union[str, Image.Image]:
|
||||
@ -83,6 +83,9 @@ async def get_img(url: str,
|
||||
:param mode: 图片模式,为空则不做修改
|
||||
:param crop: 图片裁剪,为空则不做修改
|
||||
"""
|
||||
if save_path and Path(save_path).exists():
|
||||
img = Image.open(save_path)
|
||||
else:
|
||||
try:
|
||||
async with httpx.AsyncClient() as client:
|
||||
resp = await client.get(url,
|
||||
@ -94,18 +97,6 @@ async def get_img(url: str,
|
||||
if b'error' in resp:
|
||||
return 'No Such File'
|
||||
img = Image.open(BytesIO(resp))
|
||||
if size:
|
||||
img = img.resize(size, Image.ANTIALIAS)
|
||||
if mode:
|
||||
img = img.convert(mode)
|
||||
if crop:
|
||||
img = img.crop(crop)
|
||||
if save_path:
|
||||
if isinstance(save_path, str):
|
||||
save_path = Path(save_path)
|
||||
save_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
img.save(save_path)
|
||||
return img
|
||||
except SSLCertVerificationError:
|
||||
async with httpx.AsyncClient() as client:
|
||||
resp = await client.get(url.replace('https', 'http'),
|
||||
@ -118,16 +109,16 @@ async def get_img(url: str,
|
||||
return 'No Such File'
|
||||
img = Image.open(BytesIO(resp))
|
||||
if size:
|
||||
if isinstance(size, float):
|
||||
img = img.resize((int(img.size[0] * size), int(img.size[1] * size)), Image.ANTIALIAS)
|
||||
elif isinstance(size, tuple):
|
||||
img = img.resize(size, Image.ANTIALIAS)
|
||||
if mode:
|
||||
img = img.convert(mode)
|
||||
if crop:
|
||||
img = img.crop(crop)
|
||||
if save_path:
|
||||
if isinstance(save_path, str):
|
||||
if save_path and not Path(save_path).exists():
|
||||
save_path = Path(save_path)
|
||||
save_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
img.save(save_path)
|
||||
return img
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
|
@ -28,11 +28,20 @@ class MessageBuild:
|
||||
) -> MessageSegment:
|
||||
if isinstance(img, str) or isinstance(img, Path):
|
||||
img = load_image(path=img, size=size, mode=mode, crop=crop)
|
||||
else:
|
||||
if size:
|
||||
if isinstance(size, float):
|
||||
img = img.resize((int(img.size[0] * size), int(img.size[1] * size)), Image.ANTIALIAS)
|
||||
elif isinstance(size, tuple):
|
||||
img = img.resize(size, Image.ANTIALIAS)
|
||||
if crop:
|
||||
img = img.crop(crop)
|
||||
if mode:
|
||||
img = img.convert(mode)
|
||||
bio = BytesIO()
|
||||
img = img.convert(mode)
|
||||
img.save(bio, format='JPEG' if mode == 'RGB' else 'PNG', quality=quality)
|
||||
img_b64 = 'base64://' + base64.b64encode(bio.getvalue()).decode()
|
||||
return MessageSegment.image(img_b64)
|
||||
return MessageSegment.image(bio)
|
||||
|
||||
@classmethod
|
||||
async def StaticImage(cls,
|
||||
@ -58,8 +67,7 @@ class MessageBuild:
|
||||
bio = BytesIO()
|
||||
img = img.convert(mode)
|
||||
img.save(bio, format='JPEG' if mode == 'RGB' else 'PNG', quality=quality)
|
||||
img_b64 = 'base64://' + base64.b64encode(bio.getvalue()).decode()
|
||||
return MessageSegment.image(img_b64)
|
||||
return MessageSegment.image(bio)
|
||||
|
||||
@classmethod
|
||||
def Text(cls, text: str) -> MessageSegment:
|
||||
|
Loading…
Reference in New Issue
Block a user