3dmodelmaker / src /front_card_image.py
2Nike2
Can upload user original card design.
014abd7
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
from src.constants import front_card_img_dict
# Pixel position information for each area of the card image
# Picture
PICTURE_LT_XY = (65, 188)
PICTURE_RB_XY = (802, 925)
PICTURE_SIZE = (PICTURE_RB_XY[0] - PICTURE_LT_XY[0], PICTURE_RB_XY[1] - PICTURE_LT_XY[1])
# Title
# Create some margin
TITLE_LT_XY = (65, 45)
TITLE_RB_XY = (647, 132)
TITLE_SIZE = (TITLE_RB_XY[0] - TITLE_LT_XY[0], TITLE_RB_XY[1] - TITLE_LT_XY[1])
# Main Body of Description
DESCRIPTION_LT_XY = (46, 972)
DESCRIPTION_RB_XY = (810, 1174)
DESCRIPTION_SIZE = (DESCRIPTION_RB_XY[0] - DESCRIPTION_LT_XY[0], DESCRIPTION_RB_XY[1] - DESCRIPTION_LT_XY[1])
# Font information
# Ming Typeface
font_selif_path = 'data/fonts/SourceHanSerif-Bold.otf'
# Gothic Typeface
font_sanselif_path = 'data/fonts/SourceHanSans-Bold.otf'
def crop_center(pil_img, crop_width, crop_height):
img_width, img_height = pil_img.size
return pil_img.crop(((img_width - crop_width) // 2,
(img_height - crop_height) // 2,
(img_width + crop_width) // 2,
(img_height + crop_height) // 2))
def crop_max_square(pil_img):
return crop_center(pil_img, min(pil_img.size), min(pil_img.size))
def create_card_image(card_frame_bytearray, img_bytearray, option_dict):
# Loading and Cropping of Picture
picture_img = Image.open(img_bytearray)
picture_img = crop_max_square(picture_img)
picture_img = picture_img.resize(PICTURE_SIZE)
# Loading of Card Frame
card_img = Image.open(card_frame_bytearray)
# Embedding a Picture in the Card
card_img.paste(picture_img, PICTURE_LT_XY)
## Preparing for editting the card image
card_imgdraw = ImageDraw.Draw(card_img)
# Embedding the Title
# (Support for multiple lines if needed)
title_font_size = 100
while True:
title_font = ImageFont.truetype(font_selif_path, title_font_size)
title_bbox = card_imgdraw.textbbox(TITLE_LT_XY , option_dict['γ‚Ώγ‚€γƒˆγƒ«'], title_font)
if (title_bbox[2] <= TITLE_RB_XY[0] and title_bbox[3] <= TITLE_RB_XY[1]) or title_font_size <= 30:
break
title_font_size -= 1
card_imgdraw.text((TITLE_LT_XY[0], int((TITLE_LT_XY[1] + TITLE_RB_XY[1]) / 2)), option_dict['γ‚Ώγ‚€γƒˆγƒ«'], fill='black', font=title_font, anchor='lm')
# Embedding the Description Text
description_font = ImageFont.truetype(font_sanselif_path, 40)
description_list = []
description_length = len(option_dict['θͺ¬ζ˜Žζ–‡'])
temp_start = 0
for i in range(description_length):
temp_end = i
description_line_bbox = card_imgdraw.textbbox((0, 0), option_dict['θͺ¬ζ˜Žζ–‡'][temp_start:temp_end+1], description_font)
if description_line_bbox[2] > DESCRIPTION_SIZE[0]:
description_list.append(option_dict['θͺ¬ζ˜Žζ–‡'][temp_start:temp_end])
temp_start = i
description_list.append(option_dict['θͺ¬ζ˜Žζ–‡'][temp_start:])
description_display = '\n'.join(description_list)
card_imgdraw.text(DESCRIPTION_LT_XY, description_display, fill='black', font=description_font)
# Outputting Binary Data
output_img_bytearray = BytesIO()
card_img.convert('RGB').save(output_img_bytearray, "JPEG", quality=95)
output_img_bytearray.seek(0) # Seek to the beginning of the image, otherwise it results in empty data
return output_img_bytearray