2025-07-21 18:47:59 +08:00

100 lines
3.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)