193 lines
7.5 KiB
Python
193 lines
7.5 KiB
Python
import asyncio
|
|
import os
|
|
import random
|
|
import traceback
|
|
import uuid
|
|
|
|
from PIL import Image, ImageDraw, ImageFont, ImageFilter
|
|
|
|
from .utils import autofix_character
|
|
|
|
assets_path = os.path.abspath('./assets/arcaea')
|
|
|
|
|
|
def makeShadow(image, iterations, border, offset, backgroundColour, shadowColour):
|
|
fullWidth = image.size[0] + abs(offset[0]) + 2 * border
|
|
fullHeight = image.size[1] + abs(offset[1]) + 2 * border
|
|
shadow = Image.new(image.mode, (fullWidth, fullHeight), backgroundColour)
|
|
shadowLeft = border + max(offset[0], 0)
|
|
shadowTop = border + max(offset[1], 0)
|
|
shadow.paste(shadowColour,
|
|
(shadowLeft, shadowTop,
|
|
shadowLeft + image.size[0],
|
|
shadowTop + image.size[1]))
|
|
for i in range(iterations):
|
|
shadow = shadow.filter(ImageFilter.BLUR)
|
|
imgLeft = border - min(offset[0], 0)
|
|
imgTop = border - min(offset[1], 0)
|
|
shadow.paste(image, (imgLeft, imgTop))
|
|
return shadow
|
|
|
|
|
|
def drawb30(Username, b30, r10, ptt, character, path='', official=False):
|
|
# background
|
|
if not official:
|
|
bgimgpath = f'{assets_path}/world/'
|
|
else:
|
|
bgimgpath = f'{assets_path}/world_official/'
|
|
bglist = os.listdir(bgimgpath)
|
|
bgr = random.randint(0, len(bglist) - 1)
|
|
bg = Image.open(bgimgpath + f'/{bglist[bgr]}').convert("RGBA")
|
|
bg = bg.resize((bg.size[0] * 2, bg.size[1] * 2))
|
|
offset = random.randint(0, 1024)
|
|
if not official:
|
|
if bg.width < 2489:
|
|
bgmut = 2489 / bg.width
|
|
bg = bg.resize((int(bg.width * bgmut), int(bg.height * bgmut)))
|
|
b30img = bg.crop((0, offset, 2489, 1400 + offset))
|
|
else:
|
|
if bg.width < 1975:
|
|
bgmut = 1975 / bg.width
|
|
bg = bg.resize((int(bg.width * bgmut), int(bg.height * bgmut)))
|
|
b30img = bg.crop((0, offset, 1975, 1610 + offset))
|
|
|
|
if not official:
|
|
# triangle
|
|
tg = Image.open(f'{assets_path}/triangle.png')
|
|
b30img.alpha_composite(tg.convert("RGBA"), (1580, 550))
|
|
# character
|
|
character_img_path = f'{assets_path}/char/{str(character)}.png'
|
|
if os.path.exists(character_img_path):
|
|
character = Image.open(character_img_path)
|
|
b30img.alpha_composite(character.convert("RGBA"), (1660, 350))
|
|
else:
|
|
asyncio.create_task(autofix_character(str(character)))
|
|
|
|
# usercard overlay
|
|
cardoverlay = Image.open(f'{assets_path}/card_overlay.png')
|
|
if not official:
|
|
b30img.alpha_composite(cardoverlay.convert("RGBA"), (1750, 1227))
|
|
else:
|
|
b30img.alpha_composite(makeShadow(cardoverlay.convert("RGBA"), 2, 3, [3, 3], 'rgba(0,0,0,0)', '#000000'),
|
|
(b30img.width - 500, 68))
|
|
# ptt
|
|
pttimg = 'off'
|
|
if ptt is not None and isinstance(ptt, (int, float)):
|
|
if ptt >= 13.00:
|
|
pttimg = 7
|
|
elif ptt >= 12.50:
|
|
pttimg = 6
|
|
elif ptt >= 12.00:
|
|
pttimg = 5
|
|
elif ptt >= 11.00:
|
|
pttimg = 4
|
|
elif ptt >= 10.00:
|
|
pttimg = 3
|
|
elif ptt >= 7.00:
|
|
pttimg = 2
|
|
elif ptt >= 3.50:
|
|
pttimg = 1
|
|
elif ptt >= 0:
|
|
pttimg = 0
|
|
pttimg = Image.open(f'{assets_path}/ptt/rating_{str(pttimg)}.png')
|
|
pttimg = pttimg.resize((75, 75))
|
|
if not official:
|
|
b30img.alpha_composite(pttimg.convert("RGBA"), (1775, 1226))
|
|
else:
|
|
b30img.alpha_composite(pttimg.convert("RGBA"), (b30img.width - 450, 67))
|
|
ptttext = Image.new("RGBA", (200, 200))
|
|
ptttext_width, ptttext_height = ptttext.size
|
|
font1 = ImageFont.truetype(f'{assets_path}/Fonts/Exo-SemiBold.ttf', 30)
|
|
font2 = ImageFont.truetype(f'{assets_path}/Fonts/Exo-SemiBold.ttf', 21)
|
|
if ptt is not None and isinstance(ptt, (int, float)):
|
|
rawptt = str(ptt).split('.')
|
|
ptt1 = rawptt[0]
|
|
ptt2 = rawptt[1]
|
|
if len(ptt2) < 2:
|
|
ptt2 += '0'
|
|
font1_width, font1_height = font1.getsize(ptt1 + '.')
|
|
font2_width, font2_height = font2.getsize(ptt2)
|
|
pttimg = Image.new("RGBA", (font1_width + font2_width + 4, font1_height + 4))
|
|
drawptt = ImageDraw.Draw(pttimg)
|
|
stroke_color = '#52495d'
|
|
if int(ptt1) >= 13:
|
|
stroke_color = '#81122F'
|
|
drawptt.text((0, 0), ptt1 + '.', 'white', font=font1, stroke_width=2, stroke_fill=stroke_color)
|
|
drawptt.text((font1_width, 9), ptt2, 'white', font=font2, stroke_width=2, stroke_fill=stroke_color)
|
|
else:
|
|
font1_width, font1_height = font1.getsize('--')
|
|
pttimg = Image.new("RGBA", (font1_width, font1_height))
|
|
drawptt = ImageDraw.Draw(pttimg)
|
|
drawptt.text((0, 0), '--', 'white', font=font1, stroke_width=2, stroke_fill='#52495d')
|
|
|
|
pttimg_width, pttimg_height = pttimg.size
|
|
ptttext.alpha_composite(pttimg,
|
|
(int((ptttext_width - pttimg_width) / 2), int((ptttext_height - pttimg_height) / 2)))
|
|
if not official:
|
|
b30img.alpha_composite(ptttext, (1713, 1157))
|
|
else:
|
|
b30img.alpha_composite(ptttext, (b30img.width - 512, 0))
|
|
# username
|
|
userfont = ImageFont.truetype(f'{assets_path}/Fonts/GeosansLight.ttf', 45)
|
|
textdraw = ImageDraw.Draw(b30img)
|
|
if not official:
|
|
textdraw.text((1871, 1225), Username, '#3a4853', font=userfont, stroke_width=2, stroke_fill='white')
|
|
else:
|
|
textdraw.text((b30img.width - 365, 70), Username, '#3a4853', font=userfont, stroke_width=2, stroke_fill='white')
|
|
# b30
|
|
b30font = ImageFont.truetype(f'{assets_path}/Fonts/Exo-Medium.ttf', 17)
|
|
br30 = f'B30: {str(b30)} R10: {str(r10)}'
|
|
if not official:
|
|
textdraw.text((1876, 1270), br30, '#3a4853', font=b30font, stroke_width=2, stroke_fill='white')
|
|
else:
|
|
textdraw.text((b30img.width - 360, 113), br30, '#3a4853', font=b30font, stroke_width=2, stroke_fill='white')
|
|
# disclaimer
|
|
disclaimer_font = ImageFont.truetype(f'{assets_path}/Fonts/Exo-Medium.ttf', 25)
|
|
if official:
|
|
textdraw.text(
|
|
(5,
|
|
5),
|
|
f'Based on ArcaeaLimitedAPI by Lowiro | Generated by Teahouse Studios "Akaribot"'
|
|
f'\nThis service utilizes API functionality provided by and with permission from lowiro. It is not affiliated with or endorsed by lowiro.',
|
|
'#3a4853',
|
|
font=b30font,
|
|
stroke_fill='white',
|
|
stroke_width=2)
|
|
else:
|
|
textdraw.text((b30img.width - 490, 5), f'Based on BotArcAPI | Generated by Teahouse Studios "Akaribot"',
|
|
'#3a4853', font=b30font, stroke_fill='white', stroke_width=2)
|
|
# b30card
|
|
i = 0
|
|
fname = 1
|
|
t = 0
|
|
s = 0
|
|
while True:
|
|
try:
|
|
cardimg = Image.open(os.path.abspath(f'{path}/{str(fname)}.png'))
|
|
w = (15 if not official else 115) + 345 * i
|
|
h = (15 if not official else 185)
|
|
if s == 5:
|
|
s = 0
|
|
t += 1
|
|
h = h + 220 * t
|
|
w = w - 345 * 5 * t
|
|
i += 1
|
|
cardimg = makeShadow(cardimg, 4, 9, [0, 3], 'rgba(0,0,0,0)', '#000000')
|
|
b30img.alpha_composite(cardimg, (w, h))
|
|
fname += 1
|
|
s += 1
|
|
except FileNotFoundError:
|
|
break
|
|
except Exception:
|
|
traceback.print_exc()
|
|
break
|
|
if __name__ == '__main__':
|
|
b30img.show()
|
|
else:
|
|
savefilename = os.path.abspath(f'./cache/{str(uuid.uuid4())}.jpg')
|
|
b30img.convert("RGB").save(savefilename)
|
|
return savefilename
|
|
|
|
|
|
if __name__ == '__main__':
|
|
drawb30('OasisAkdfsfari', '10.250', '10.250', 12.31, '0', official=False)
|