本文代码讲整合在:
GitHub - liangwq/Chatglm_lora_multi-gpu: chatglm多gpu用deepspeed和
这篇文章介绍如何利用VLM+diffusion模型来搭建一条文本生成海报的链路。搭建这条链路有两个应用:1.实际的业务中需要批量生产文字+图海报可以用,2.可以用来造训练数据。
首先介绍下这篇文章的整体框架安排:
1.生图模块
2.字排版模块
3.图文混合模块
4.图审核验证模块
生成模块
部署文本生成图片模型pixart-sigma:
1.安装环境和下载源码
conda create -n pixart python==3.9.0
conda activate pixart
conda install pytorch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2 pytorch-cuda=11.7 -c pytorch -c nvidiagit clone https://github.com/PixArt-alpha/PixArt-sigma.git
cd PixArt-sigma
pip install -r requirements.txt
2.下载模型
# SDXL-VAE, T5 checkpoints
git lfs install
git clone https://huggingface.co/PixArt-alpha/pixart_sigma_sdxlvae_T5_diffusers output/pretrained_models/pixart_sigma_sdxlvae_T5_diffusers# PixArt-Sigma checkpoints
python tools/download.py # environment eg. HF_ENDPOINT=https://hf-mirror.com can use for HuggingFace mirror
3.启动模型后台
python scripts/interface.py --model_path output/pretrained_models/PixArt-Sigma-XL-2-2k-MS.pth --image_size 2048 --port 6006
4.gradio_cleint前端API方式生成图片
from gradio_client import Client#建立后台服务器链接
client = Client("http://0.0.0.0:6006")
#查看请求参数
client.view_api(return_format="dict")#传参请求生成图
out_data = client.predict("An adorable girl with curly hair, innocently laughing with a big smile, looking very happy Poster style --ar 9:16","dpm-solver",14,4.5,0,True)
#生成图片可视化
import matplotlib.pyplot as plt
from PIL import Image# 图片地址
image_path = out_data[0]# 打开并显示图片
img = Image.open(image_path)
plt.imshow(img)
plt.axis('off') # 关闭坐标轴
plt.show()
使用Gradio客户端来与一个后台服务器建立连接,并通过传递参数请求生成一张图片。首先建立了与服务器的连接,然后查看了请求参数的格式。接着使用client.predict
方法传递参数来生成一张图片,参数包括描述图片内容的文本、模型名称、以及其他参数。生成的图片保存在out_data
中,然后通过Matplotlib和PIL库来打开和显示这张图片。
具体步骤包括:
- 建立与服务器的连接。
- 查看请求参数的格式。
- 使用
client.predict
方法传递参数请求生成一张图片。 - 从生成的结果中获取图片地址。
- 使用PIL库打开并显示生成的图片。
最后一段代码使用Matplotlib显示了生成的图片,关闭了坐标轴以便更清晰地展示图片内容。
文字排版模块
def auto_text_layout(inputext=[], x=0,y=0,row_spacing=100, col_spacing=80, vertical=True, font="SimSun", color=(255, 255, 255, 0)):if vertical:output=[] y0=yfor text in inputext:for char in list(text):output.append({"content": char,"position": (x, y),"font": font,"color": color})y += col_spacingy= y0x += row_spacingelse:output=[]x0 = xfor text in inputext:for char in list(text):output.append({"content": char,"position": (x, y),"font": font,"color": color})x += row_spacingx=x0y += col_spacingreturn output
text_lines = [' 悠闲的夏日,',' 不在乎目的地,', '在乎的是沿途的风景', ' 以及看风景的心情.']
auto_text=auto_text_layout(inputext=text_lines, x=510,y=85,row_spacing=48, col_spacing=63, vertical=False, font="SimSun", color=(255, 255, 255, 0))
print(auto_text)
这段代码定义了一个函数auto_text_layout
,用于根据输入的文本内容和参数生成一个文本布局的列表。函数的参数包括输入文本列表inputext
,起始坐标x
和y
,行间距row_spacing
,列间距col_spacing
,布局方向vertical
,字体font
和颜色color
。
函数根据vertical
参数的取值,决定文本是垂直排列还是水平排列。如果是垂直排列,函数会按列逐个字符添加到输出列表中;如果是水平排列,函数会按行逐个字符添加到输出列表中。每个字符的信息包括内容、位置、字体和颜色。
在代码中,定义了一个包含多行文本的列表text_lines
,然后调用auto_text_layout
函数生成文本布局。生成的文本布局存储在auto_text
变量中,并通过print(auto_text)
打印出来。
这段代码是一个用于生成文本布局的函数,并展示了如何使用该函数来布局指定的文本内容。
合图渲染模块
import os
import json
from PIL import Image, ImageDraw, ImageFont
import cv2# 设置海报模板路径、文字内容、输出目录等参数
template_path = 'boy_autumn.png' # 海报模板路径
text_lines = [{'content': '悠闲的夏日', 'position': (300, 150), 'color': (0, 0, 0, 0)},{'content': ' 悠闲的夏日\n不在乎目的地,在乎的是沿途的风景,以及看风景的心情。', 'position': (300, 200), 'color': (0, 255, 0)},{'content': '以及看风景的心情。', 'position': (300, 250), 'color': (0, 0, 255)}
] # 文字内容、位置和颜色的列表text_lines = [{'content': '悠闲的夏日,', 'position': (300, 150), 'color': (255, 255, 255, 0)}, # 淡青色{'content': '不在乎目的地,', 'position': (310, 210), 'color': (126, 200, 190,1)}, # 淡绿色{'content': '在乎的是沿途的风景', 'position': (330, 270), 'color': (16, 175, 220,1)}, # 淡绿色{'content': '以及看风景的心情。', 'position': (360, 330), 'color': (13, 180, 180,1)} # 淡黄色
] # 文字内容、位置和颜色的列表
text_lines = auto_text
output_dir = 'output_posters' # 输出目录
font_path = '/Library/Fonts/Alibaba-PuHuiTi-Heavy.otf' # 字体文件路径
font_size = 42 # 字体大小
text_angle = 290 # 文字旋转角度(竖排)# 确保输出目录存在
if not os.path.exists(output_dir):os.makedirs(output_dir)# 加载模板图片
template_image = Image.open(template_path)# 创建一个可以在Pillow中使用的字体对象
font = ImageFont.truetype(font_path, font_size)# 创建一个可以在Pillow中使用的绘图对象
draw = ImageDraw.Draw(template_image)# 在指定位置添加文字
for line in text_lines:draw.text(line['position'], line['content'], font=font, fill=line['color'], rotation=text_angle)# 保存处理后的图片
output_path = os.path.join(output_dir, 'poster_with_multiple_lines.jpg')
template_image.save(output_path)# 如果需要进行图层融合和模糊处理,可以使用OpenCV
# 读取处理后的图片
image = cv2.imread(output_path)# 这里可以添加OpenCV的图层融合和模糊处理代码
# 例如,使用高斯模糊
blurred_image = cv2.GaussianBlur(image, (5, 5), 0)# 保存模糊处理后的图片
cv2.imwrite(os.path.join(output_dir, 'blurred_poster.jpg'), blurred_image)print("海报生成和处理完成。")
这段代码实现了往一张图片中添加文字渲染,并在需要时进行图层融合和模糊处理。以下是代码的主要步骤和解释:
- 设置参数:
template_path
: 海报模板的路径。text_lines
: 包含要添加到海报上的文字内容、位置和颜色的列表。output_dir
: 输出目录。font_path
: 字体文件的路径。font_size
: 字体大小。text_angle
: 文字旋转角度(竖排)。
- 加载模板图片:
使用PIL库中的Image.open
方法加载海报模板图片。 - 创建字体对象:
使用指定的字体文件路径和字体大小创建一个可以在Pillow中使用的字体对象。 - 创建绘图对象:
使用ImageDraw.Draw
方法创建一个可以在Pillow中使用的绘图对象。 - 添加文字到图片:
遍历text_lines
列表,根据每个字体的位置、内容和颜色,使用draw.text
方法将文字添加到模板图片上。 - 保存处理后的图片:
使用template_image.save
方法将处理后的图片保存到指定的输出路径。 - 图层融合和模糊处理(使用OpenCV):
- 读取处理后的图片。
- 进行图层融合和模糊处理,例如使用高斯模糊。
- 保存模糊处理后的图片到输出目录。
- 最后,打印出"海报生成和处理完成。"
将指定的文字内容添加到海报模板图片中,并在需要时进行模糊处理。
审核模块
from dashscope import MultiModalConversation
import dashscope
dashscope.api_key ='把你申请的qwenvl api-key放这边'
def call_with_local_file():"""Sample of use local file.linux&mac file schema: file:///home/images/test.pngwindows file schema: file://D:/images/abc.png"""local_file_path1 = 'file:///Users/**/output_posters/poster_with_multiple_lines.jpg'local_file_path2 = 'file://The_local_absolute_file_path2'messages = [{'role': 'system','content': [{'text': 'You are a helpful assistant.'}]}, {'role':'user','content': [{'image': local_file_path1},{'text': '请描述这张图,这张图中文字放置的位置合理吗?符合审美需求吗?\1.如果合理请回复是,并给出合理原因\2.如果不合理给出理由和建议\3.如果有建议请给出文字合适放置的坐标位置\4.如果不合理给出字体大小建议\5.如果不合理给出字体颜色建议\6.json格式输出回答结果'},]}]response = MultiModalConversation.call(model=MultiModalConversation.Models.qwen_vl_chat_v1, messages=messages)print(response)if __name__ == '__main__':call_with_local_file()
这份代码实现了使用 DashScope 的 MultiModalConversation API 对一张本地图片进行审美评估。
- 导入必要的库:
dashscope
: 用于调用 DashScope 的 MultiModalConversation API。MultiModalConversation
: 用于创建和调用多模态对话。
- 设置 API 密钥:
将你申请的 DashScope API 密钥设置为dashscope.api_key
的值。 - 定义
**call_with_local_file()**
函数:
- 这个函数演示了如何使用本地文件作为输入。
- 定义了两个本地文件路径
local_file_path1
和local_file_path2
。 - 构建了一个消息列表,其中包含一个系统消息和一个用户消息。
- 系统消息指定了助手的角色为"You are a helpful assistant."。
- 用户消息包含了两个部分:
- 一个图像,使用
local_file_path1
指定的本地文件路径。 - 一个文本,包含了对图像的评估要求。
- 一个图像,使用
- 调用 MultiModalConversation.call() 方法:
- 使用
MultiModalConversation.call()
方法调用 DashScope 的 MultiModalConversation API。 - 传入了
MultiModalConversation.Models.qwen_vl_chat_v1
作为模型参数,这是一个预训练的多模态对话模型。 - 将前面构建的消息列表作为
messages
参数传入。
- 打印响应结果:
将 API 调用的响应结果打印出来。
这段代码的主要功能是:
- 加载一张本地图片作为输入。
- 构建一个包含图像和文本的多模态消息。
- 使用 DashScope 的 MultiModalConversation API 对图像进行审美评估。
- 打印出 API 的响应结果。
这个代码可以用于对图像的文字布局、字体大小和颜色等进行自动化评估和建议。通过调用 DashScope 的多模态对话 API,可以获得专业的审美意见和优化建议。
小结:
上面介绍了一条使用diffusion+VLM+code方式实现的海报生成链路。链路已经具备了一键生成和图片审核的能力,但是现在只给到了一种图层合图的实现。
1.有兴趣的朋友可以试试如何在现有代码基础上增加controlnet做字图融合生成。
2.同时可以考虑下如何让LLM模型来自动根据用户输入的简单需求来生成自动生成文本描述生成图,让这个工作流更智能强大。
3.同时还可以考虑如何让大模型对已经又的参考图做描述,批量生成更多类似风格图
大家可以先思考,后面我也会给出我的实现方案。