Add File
This commit is contained in:
286
main/gen_img_servie.py
Normal file
286
main/gen_img_servie.py
Normal 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()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user