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()