This commit is contained in:
2025-11-19 19:42:50 +08:00
parent 468b84c6af
commit db4903f4e6

286
main/gen_img_servie.py Normal file
View File

@@ -0,0 +1,286 @@
from PIL import Image, ImageDraw, ImageFont
import os
from parse_html import parse_html_to_ppt,parse_html_to_poster
#处理多行文本
def draw_multiline_text(draw, text, position, max_width, font, fill, line_spacing=10, only_calc=False):
"""
在指定区域内绘制自动换行的文本
参数:
draw - ImageDraw对象
text - 要绘制的文本
position - 起始位置 (x, y)
max_width - 最大行宽
font - 字体对象
fill - 文本颜色
line_spacing - 行间距 (默认10)
"""
x, y = position
lines = []
# 如果文本包含换行符,先按换行符分割
paragraphs = text.split('\n')
for paragraph in paragraphs:
words = []
# 中英文混合处理:将每个字符视为独立的"词"
for char in paragraph:
words.append(char)
# 添加空格字符作为可能的断点
if char.isspace():
words.append('')
space_width = draw.textlength(' ', font=font)
current_line = []
current_width = 0
for word in words:
word_width = draw.textlength(word, font=font)
# 如果当前行宽度加上新词宽度超过最大宽度
if current_width + word_width > max_width and current_line:
# 将当前行添加到行列表
lines.append(''.join(current_line))
current_line = [word]
current_width = word_width
else:
current_line.append(word)
current_width += word_width
# 添加最后一行
if current_line:
lines.append(''.join(current_line))
# 计算行高
_, _, _, line_height = font.getbbox("A")
# 绘制每一行文本
for line in lines:
if not only_calc:
draw.text((x, y), line, fill=fill, font=font)
y += line_height + line_spacing
return y
#绘制表格
def draw_table(draw,headers,data,table_top,table_left,table_width,header_font,data_font,text_color,header_color):
data.pop(0)
cell_height = 65 # 固定单元格高度
rows = len(data)+1
cols = len(headers)
table_height = cell_height * rows
cell_width = table_width // cols
# 绘制表头圆角矩形背景
draw.rounded_rectangle(
(table_left-10, table_top, table_left+table_width+10, table_top+cell_height+15),
radius=40,
fill=header_color, # 深蓝色背景
outline=header_color
)
# # 绘制表头分割线
for i in range(1, cols):
x = table_left + i * cell_width
# 绘制垂直线条,稍微短一点以避开圆角
draw.line(
[(x, table_top + 10), (x, table_top + cell_height)],
fill=(255, 255, 255, 180), # 半透明白色
width=2
)
for col in range(cols):
text = headers[col]
# 使用textbbox计算文本尺寸
text_bbox = draw.textbbox((0, 0), text, font=header_font)
text_width = text_bbox[2] - text_bbox[0]
text_height = text_bbox[3] - text_bbox[1]
x = table_left + col * cell_width + (cell_width - text_width) // 2
y = table_top + (cell_height - text_height) // 2
draw.text((x, y), text, fill=(255, 255, 230), font=header_font)
#微调一下数据表格的大小和位置下移15
table_top +=15
table_width = table_width - 40
table_left +=20
cell_width = table_width // cols
# 绘制数据行
for row in range(len(data)):
for col in range(cols):
# 计算单元格位置
x1 = table_left + col * cell_width
y1 = table_top + (row + 1) * cell_height
x2 = x1 + cell_width
y2 = y1 + cell_height
# 交替行颜色
if row % 2 == 0:
bg_color = (248, 250, 253) # 浅色行
else:
bg_color = (240, 245, 251) # 更浅的蓝色行
# 绘制单元格背景
draw.rectangle([x1, y1, x2, y2], fill=bg_color)
# 添加数据
text = data[row][col]
# 使用textbbox计算文本尺寸
text_bbox = draw.textbbox((0, 0), text, font=data_font)
text_width = text_bbox[2] - text_bbox[0]
text_height = text_bbox[3] - text_bbox[1]
x = x1 + 15
# 默认y位置
y = y1 + (cell_height - text_height) // 2
draw.text((x, y), text, fill=text_color, font=data_font)
# 绘制网格线
for i in range(1, rows):
y = table_top + i * cell_height
draw.line(
[(table_left, y), (table_left+table_width, y)],
fill=(225, 232, 243),
width=1
)
for i in range(1, cols):
x = table_left + i * cell_width
draw.line(
[(x, table_top + cell_height), (x, table_top+table_height)],
fill=(225, 232, 243),
width=1
)
#表格边线,三条,, # 深蓝色背景
draw.line(
[(table_left, table_top + cell_height-5), (table_left, table_top+table_height)],
fill=header_color,
width=2
)
draw.line(
[(table_left+table_width, table_top + cell_height-5), (table_left+table_width, table_top+table_height)],
fill=header_color,
width=2
)
draw.line(
[(table_left, table_top + table_height), (table_left+table_width, table_top+table_height)],
fill=header_color,
width=2
)
return table_top+table_height+20
# 辅助函数:获取文本尺寸
def get_text_size(draw,text, font):
bbox = draw.textbbox((0, 0), text, font=font)
return bbox[2] - bbox[0], bbox[3] - bbox[1]
#ppt模板101的图片
def create_ppt_images(main_color=None):
background_colors = [
{"name": "深空蓝", "hex": "#0D4D4B", "rgb": (13, 77, 75)},
{"name": "紫罗兰", "hex": "#4A306D", "rgb": (74, 48, 109)},
{"name": "海军蓝", "hex": "#003366", "rgb": (0, 51, 102)},
{"name": "森林绿", "hex": "#22577A", "rgb": (34, 87, 122)},
{"name": "暗玫瑰红", "hex": "#E0115F", "rgb": (224, 17, 95)},
{"name": "橄榄绿", "hex": "#556B2F", "rgb": (85, 107, 47)},
{"name": "深紫", "hex": "#35063E", "rgb": (53, 6, 62)},
{"name": "宝石蓝", "hex": "#0F52BA", "rgb": (15, 82, 186)},
]
#如果为空则随机选择
if not main_color:
import random
main_color = background_colors[random.randint(0,len(background_colors)-1)]["rgb"]
#1. 主图
#图片尺寸1080p的电脑尺寸
width, height = 1920, 1080
# 创建背景画布
img = Image.new('RGBA', (width, height), (255,255,255,0))
draw = ImageDraw.Draw(img)
# 绘制矩形背景
m_height=600
draw.rectangle(
(0, (height-m_height)//2, width, (height-m_height)//2+m_height),
fill=main_color,
outline=main_color
)
img.save("pic/101_main.png")
#2. 引导图
#图片尺寸1080p的电脑尺寸
width, height = 1920, 450
# 创建背景画布
img = Image.new('RGB', (width, height), (255,255,255))
draw = ImageDraw.Draw(img)
# 绘制矩形背景
draw.rectangle(
(0, 0, width, height),
fill=main_color,
outline=main_color
)
img.save("pic/101_catalog_w.png")
#3. 目录图
#图片尺寸1080p的电脑尺寸
width, height = 600, 1080
# 创建背景画布
img = Image.new('RGB', (width, height), (255,255,255))
draw = ImageDraw.Draw(img)
# 绘制矩形背景
draw.rectangle(
(0, 0, width, height),
fill=main_color,
outline=main_color
)
img.save("pic/101_catalog.png")
#4. 标题图
#图片尺寸1080p的电脑尺寸
width, height = 1920, 120
# 创建背景画布
img = Image.new('RGB', (width, height), (255,255,255))
draw = ImageDraw.Draw(img)
# 绘制矩形背景
draw.rectangle(
(0, 0, width, height),
fill=main_color,
outline=main_color
)
img.save("pic/101_title.png")
return main_color
if __name__=="__main__":
#create_ppt_images("#0F52BA")
create_ppt_images()