新增角色深渊详情可莉 (#499)

This commit is contained in:
Wuyi无疑 2023-05-03 23:10:49 +08:00
parent e32e1637a7
commit 0f2807c346
12 changed files with 184 additions and 7 deletions

View File

@ -3,7 +3,6 @@ from pathlib import Path
from typing import Union
from PIL import Image, ImageDraw
from gsuid_core.logger import logger
from .gs_config import gsconfig

View File

@ -9,6 +9,10 @@ from ..genshinuid_xkdata import draw_xk_abyss_img
from ..genshinuid_help.draw_help_card import draw_help_img
from ..genshinuid_guide.get_abyss_data import generate_data
from ..utils.resource.generate_char_card import create_all_char_card
from ..genshinuid_xkdata.get_all_char_data import (
save_all_char_info,
save_all_abyss_rank,
)
async def all_start():
@ -19,6 +23,8 @@ async def all_start():
await create_all_char_card()
await draw_xk_abyss_img()
await generate_data()
await save_all_char_info()
await save_all_abyss_rank()
except Exception as e:
logger.exception(e)

View File

@ -6,11 +6,10 @@ from http.cookies import SimpleCookie
from typing import Any, List, Tuple, Union, Literal
import qrcode
from qrcode.constants import ERROR_CORRECT_L
from gsuid_core.bot import Bot
from gsuid_core.models import Event
from gsuid_core.logger import logger
from qrcode.constants import ERROR_CORRECT_L
from gsuid_core.segment import MessageSegment
from ..utils.mys_api import mys_api

View File

@ -7,6 +7,7 @@ from gsuid_core.models import Event
from gsuid_core.aps import scheduler
from ..utils.image.convert import convert_img
from .draw_char_abyss import draw_char_abyss_info
from .draw_abyss_total import TOTAL_IMG, draw_xk_abyss_img
from .get_all_char_data import save_all_char_info, save_all_abyss_rank
@ -32,3 +33,9 @@ async def send_abyss_pic(bot: Bot, ev: Event):
img = await convert_img(TOTAL_IMG)
await bot.logger.info('获得深渊概览图片成功!')
await bot.send(img)
@sv_get_abyss_database.on_prefix(('角色深渊详情', '角色深渊'), block=True)
async def send_char_abyss_pic(bot: Bot, ev: Event):
im = await draw_char_abyss_info(ev.text)
await bot.send(im)

View File

@ -0,0 +1,140 @@
from pathlib import Path
from typing import Union
from PIL import Image, ImageDraw
from ..utils.image.convert import convert_img
from ..utils.map.GS_MAP_PATH import artifact2attr
from .get_all_char_data import get_akasha_char_data
from ..utils.fonts.genshin_fonts import gs_font_20, gs_font_40
from ..utils.image.image_tools import get_color_bg, draw_pic_with_ring
from ..utils.resource.generate_char_card import create_single_item_card
from ..utils.map.name_covert import name_to_avatar_id, alias_to_char_name
from ..utils.resource.RESOURCE_PATH import REL_PATH, CHAR_PATH, WEAPON_PATH
black = (10, 10, 10)
grey = (40, 40, 40)
green = (205, 255, 168)
red = (255, 168, 168)
TEXT_PATH = Path(__file__).parent / 'texture2d'
rank_dict = {
90: (189, 64, 64),
80: (189, 64, 148),
60: (95, 64, 189),
40: (64, 140, 189),
20: (64, 189, 125),
0: (200, 200, 200),
}
async def draw_char_abyss_info(char_name: str) -> Union[bytes, str]:
char_name = await alias_to_char_name(char_name)
char_id = await name_to_avatar_id(char_name)
# _char_id = char_id[1:].lstrip('0')
char_useage_rank = []
char_img = Image.open(CHAR_PATH / f'{char_id}.png')
char_pic = await draw_pic_with_ring(char_img, 264)
_data = await get_akasha_char_data(char_name)
if _data is None:
return '没有该角色的数据...'
all_char_info, char_useage_rank = _data[0], _data[1]
char_useage_rank.sort(key=lambda d: int(d['v']))
title_bg = Image.open(TEXT_PATH / 'title_bg.png')
# 计算宽高
h = 1080 + len(char_useage_rank) * 30
# 开始绘图
img = await get_color_bg(900, h, '_abyss_char')
_img = Image.new('RGBA', img.size)
img.paste(char_pic, (300, 118), char_pic)
img.paste(title_bg, (0, 400), title_bg)
# 基础文字部分
img_draw = ImageDraw.Draw(_img)
img_draw.text((450, 450), f'{char_name}的深渊统计', 'White', gs_font_40, 'mm')
# 绘图
r = 20
bg_color = (255, 255, 255, 120)
img_draw.rounded_rectangle((24, 538, 876, 746), r, bg_color)
img_draw.rounded_rectangle((24, 761, 876, 969), r, bg_color)
img_draw.rounded_rectangle((24, 988, 876, h - 40), r, bg_color)
_start = 1020
bar_bg = (0, 0, 0, 128)
for index, rank in enumerate(char_useage_rank):
_intent = _start + index * 30
y1, y2 = _intent + 9, _intent + 23
img_draw.rounded_rectangle((108, y1, 708, y2), r, bar_bg)
d = float(rank["d"])
_pixel = int((d / 100) * 600)
for _p in rank_dict:
if d >= _p:
fill = rank_dict[_p]
break
else:
fill = (255, 255, 255)
img_draw.rounded_rectangle((108, y1, 108 + _pixel, y2), r, fill)
value = f'{rank["d"]}% / {rank["r"]}'
img_draw.text(
(37, 16 + _intent), f'版本{rank["v"]}', 'Black', gs_font_20, 'lm'
)
img_draw.text((730, 16 + _intent), value, 'Black', gs_font_20, 'lm')
img.paste(_img, (0, 0), _img)
# 开始
for index, weapon in enumerate(all_char_info['weapons']):
if weapon['name'] == '渔获':
weapon_name = '「渔获」'
else:
weapon_name = weapon['name']
weapon_img = Image.open(WEAPON_PATH / f'{weapon_name}.png')
item = await create_single_item_card(weapon_img, weapon['rarity'])
item_draw = ImageDraw.Draw(item)
weapon_rate = weapon['rate'] + '%'
item_draw.text((128, 280), weapon_rate, 'Black', gs_font_40, 'mm')
item = item.resize((128, 155))
img.paste(item, (47 + 135 * index, 565), item)
if index >= 5:
break
for index, equip in enumerate(all_char_info['equips']):
item_list = []
item_type = 0
for set in equip['set_list']:
for part in artifact2attr:
if artifact2attr[part] == set['name']:
part_name = part
break
else:
part_name = '冰风迷途的勇士'
item = Image.open(REL_PATH / f'{part_name}.png')
item_list.append(item)
item_type += int(set['count'])
item = await create_single_item_card(item_list, '5')
item_draw = ImageDraw.Draw(item)
equip_rate = equip['rate'] + '%'
item_draw.text((128, 280), equip_rate, 'Black', gs_font_40, 'mm')
item_draw.rounded_rectangle((200, 20, 240, 60), 15, (255, 255, 255))
item_draw.text((220, 40), f'{item_type}', 'Black', gs_font_40, 'mm')
item = item.resize((128, 155))
img.paste(item, (47 + 135 * index, 788), item)
if index >= 5:
break
return await convert_img(img)

View File

@ -22,13 +22,13 @@ abyss_rank_path = DATA_PATH / 'abyss_rank.json'
async def save_all_char_info():
all_char_info = await get_akasha_all_char_info()
async with aiofiles.open(all_char_info_path, 'w') as f:
await f.write(str(all_char_info))
await f.write(json.dumps(all_char_info))
async def save_all_abyss_rank():
abyss_rank = await get_akasha_abyss_rank()
async with aiofiles.open(abyss_rank_path, 'w') as f:
await f.write(str(abyss_rank))
await f.write(json.dumps(abyss_rank))
async def get_akasha_char_data(
@ -52,7 +52,7 @@ async def get_akasha_char_data(
if not char_id:
return None
_char_id = char_id.lstrip('100000').strip('0')
_char_id = char_id.lstrip('1').lstrip('0')
if _char_id not in all_char_info:
return None

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

View File

@ -1,4 +1,4 @@
from typing import Union
from typing import List, Union
from PIL import Image
from gsuid_core.logger import logger
@ -9,6 +9,32 @@ from .RESOURCE_PATH import CHAR_PATH, TEXT2D_PATH, CHAR_CARD_PATH
texture2d_path = TEXT2D_PATH / 'char_card'
async def create_single_item_card(
item_img: Union[List[Image.Image], Image.Image], star: Union[int, str]
) -> Image.Image:
if isinstance(item_img, List):
img = Image.new('RGBA', (256, 256))
for i, item in enumerate(item_img):
_intent = int(128 / (i + 1))
_intent2 = int((256 + (128 * (len(item_img) - 1))) / len(item_img))
item = item.resize((_intent2, _intent2))
img.paste(item, (128 - _intent, 128 - _intent), item)
item_img = img
if item_img.size != (256, 256):
item_img = item_img.resize((256, 256))
char_frame = Image.open(texture2d_path / 'frame.png')
char_bg = Image.open(texture2d_path / f'star{star}bg.png')
mask = Image.open(texture2d_path / 'mask.png')
img = Image.new('RGBA', (256, 310))
img_mask = Image.new('RGBA', (256, 310))
img_mask.paste(char_bg, (0, 0), char_bg)
img_mask.paste(item_img, (0, 0), item_img)
img_mask.paste(char_frame, (0, 0), char_frame)
img.paste(img_mask, (0, 0), mask)
return img
async def create_single_char_card(char_id: Union[str, int]) -> Image.Image:
if str(char_id) not in avatarId2Star_data:
logger.warning(f'资源文件夹发现异常图片{char_id}....忽略加载...')

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB