100 lines
3.7 KiB
Python
100 lines
3.7 KiB
Python
import os
|
||
from PIL import Image, ImageDraw, ImageFile, ImageFont
|
||
|
||
picSize = (1920, 1080)
|
||
itemSize = (320, 320)
|
||
margin = 50
|
||
itemNum = 10
|
||
fontSize = 26
|
||
fontMargin = 20
|
||
actualSize = (itemSize[0], itemSize[1] + fontMargin + int(fontSize * 1.5))
|
||
font = ImageFont.truetype("./font/HarmonyOS_Sans_SC_Medium.ttf", fontSize)
|
||
|
||
num = len(os.listdir('./sucai'))
|
||
# num = 10
|
||
# 计算某行的实际宽度
|
||
vSize = num * (itemSize[0] + num - 1) if num <= 5 else 5 * (itemSize[0] + num - 1)
|
||
# 计算左右边距以确保当前行居中展示
|
||
mSize = (picSize[0] - vSize) / 2 - margin * 2
|
||
# 如果只有一行,则计算居中,如果两行,则设置为200
|
||
marginTop = int(picSize[1] / 2) - int(itemSize[1] / 2) if num <= 5 else 200
|
||
nextYStart = marginTop + actualSize[1] + 50 if num > 5 else -1
|
||
nextViewSize = (num % 5) * (itemSize[0] + num - 1) if num < 10 else 5 * (itemSize[0] + num - 1)
|
||
nextMarginSize = (picSize[0] - nextViewSize) / 2 - margin * 2
|
||
print(nextMarginSize)
|
||
# colNum = int(num / 5) + 1
|
||
# # print(colNum)
|
||
|
||
def cutPic(img: ImageFile) -> Image:
|
||
# 等比放小50%
|
||
img = img.resize((int(img.width * 0.5), int(img.height * 0.5)))
|
||
left = (img.width - itemSize[0])/2
|
||
top = (img.height - itemSize[1])/2
|
||
right = (img.width + itemSize[0])/2
|
||
bottom = (img.height + itemSize[1])/2
|
||
return img.crop((left, top, right, bottom))
|
||
|
||
|
||
def drawComponent(pic: ImageFile, text: str, startX: int = 0, startY: int = 0) -> Image:
|
||
components = Image.new('RGBA', actualSize, color=(0, 0, 0, 0))
|
||
components.paste(cutPic(pic), (0, 0))
|
||
draw = ImageDraw.Draw(components)
|
||
text_bbox = draw.textbbox((0, 0), text, font=font)
|
||
# 计算文本宽度(文本框实际宽度)
|
||
text_width = text_bbox[2] - text_bbox[0]
|
||
# 计算文本居中
|
||
item_center_x = (startX + (itemSize[0] / 2))
|
||
text_y = startY + itemSize[1] + fontMargin
|
||
draw.text((item_center_x - (text_width / 2), text_y), text, fill=(255, 255, 255), font=font)
|
||
return components
|
||
|
||
|
||
|
||
backImage = Image.new('RGB', picSize, color=(255, 255, 255))
|
||
backImage.paste(Image.open('./pic/luoxiaohei.jpg'), (0, 0))
|
||
# backImage.paste(drawComponent(Image.open('./sucai/1.jpg'), "我真的很长很长很长的文本", 0, 0), (200, 200))
|
||
for idx, img in enumerate(os.listdir('./sucai')):
|
||
calc_X = int((itemSize[0] + margin) * idx + mSize) if idx < 5 else int((itemSize[0] + margin) * (idx % 5) + nextMarginSize)
|
||
calc_Y = marginTop if idx < 5 else nextYStart
|
||
print((calc_X, calc_Y))
|
||
component = drawComponent(Image.open('./sucai/' + img), img, 0, 0)
|
||
backImage.paste(component, (calc_X, calc_Y), mask=component)
|
||
|
||
|
||
# 写入结果
|
||
with open('./final.png', 'wb') as f:
|
||
backImage.save(f)
|
||
|
||
exit(0)
|
||
for idx, file in enumerate(os.listdir('./sucai')):
|
||
# 将图片修剪为指定大小
|
||
img = Image.open('./sucai/' + file)
|
||
# img = img.resize(itemSize)
|
||
# img.thumbnail(itemSize)
|
||
# 再居中裁剪
|
||
img = cutPic(img)
|
||
# 粘贴到背景图
|
||
backImage.paste(img, (int((itemSize[0] + margin) * idx + mSize) , marginTop))
|
||
# 在图片下面嵌字
|
||
draw = ImageDraw.Draw(backImage)
|
||
font = ImageFont.load_default()
|
||
# 使用24px大小的字体
|
||
|
||
# 绘制文本
|
||
# 计算文本宽度
|
||
text = "我真的很长很长很长的文本"
|
||
text_bbox = draw.textbbox((0, 0), text, font=font)
|
||
text_width = text_bbox[2] - text_bbox[0]
|
||
|
||
# 计算图片项的中心位置
|
||
item_center_x = ((itemSize[0] + margin) * idx + mSize) + (itemSize[0] / 2)
|
||
|
||
# 计算文本的起始x坐标,使其居中
|
||
text_x = item_center_x - (text_width / 2)
|
||
text_y = marginTop + itemSize[1] + fontMargin
|
||
|
||
draw.text((text_x, text_y), text, fill=(255, 255, 255), font=font)
|
||
|
||
# 写入结果
|
||
with open('./luoxiaohei.jpg', 'wb') as f:
|
||
backImage.save(f) |