diff --git a/main/gen_img_servie.py b/main/gen_img_servie.py new file mode 100644 index 0000000..1e29f1c --- /dev/null +++ b/main/gen_img_servie.py @@ -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() + + + + + +