feat: 新增生图格式和尺寸控制

新增功能:
- 支持图片格式控制:webp, jpg, png
- 新增#生图格式指令
- 新增尺寸快捷方式:正方形、横图、竖图、宽屏、手机、小图
- 使用 PIL 进行格式转换,webp 默认质量 85
- 优化文件体积:webp 比 PNG 小 14 倍(93KB vs 1.3MB)

测试结果:
-  webp 格式生成成功(1280*720 横图)
-  文件大小:93KB
-  格式验证通过:RIFF (little-endian) data
This commit is contained in:
admins 2026-05-14 01:25:23 +08:00
parent a0362e0ba8
commit d1f440a8a0
3 changed files with 186 additions and 48 deletions

View File

@ -3,7 +3,7 @@
""" """
飞书机器人消息接收与处理脚本 飞书机器人消息接收与处理脚本
接收飞书消息解析内容调用 WordPress 发布脚本 接收飞书消息解析内容调用 WordPress 发布脚本
支持 AI 图片生成 支持 AI 图片生成含格式和尺寸控制
""" """
import os import os
@ -34,6 +34,16 @@ CATEGORY_MAP = {
'guanyu': 1 'guanyu': 1
} }
# 尺寸快捷方式
SIZE_PRESETS = {
'正方形': '1024*1024',
'横图': '1280*720',
'竖图': '720*1280',
'宽屏': '1440*720',
'手机': '720*1440',
'小图': '512*512'
}
# 配置日志 # 配置日志
LOG_DIR = os.path.join(BASE_DIR, 'logs') LOG_DIR = os.path.join(BASE_DIR, 'logs')
os.makedirs(LOG_DIR, exist_ok=True) os.makedirs(LOG_DIR, exist_ok=True)
@ -165,7 +175,8 @@ class FeishuBot:
count=instruction.get('image_count', 1), count=instruction.get('image_count', 1),
model=instruction.get('image_model', None), model=instruction.get('image_model', None),
size=instruction.get('image_size', None), size=instruction.get('image_size', None),
style=instruction.get('image_style', None) style=instruction.get('image_style', None),
image_format=instruction.get('image_format', None)
) )
# 检查是否为发布+生图指令 # 检查是否为发布+生图指令
elif instruction.get('action') == 'publish_with_image': elif instruction.get('action') == 'publish_with_image':
@ -178,7 +189,8 @@ class FeishuBot:
image_count=instruction.get('image_count', 1), image_count=instruction.get('image_count', 1),
model=instruction.get('image_model', None), model=instruction.get('image_model', None),
size=instruction.get('image_size', None), size=instruction.get('image_size', None),
style=instruction.get('image_style', None) style=instruction.get('image_style', None),
image_format=instruction.get('image_format', None)
) )
# 检查是否为发布指令 # 检查是否为发布指令
elif instruction.get('action') == 'publish': elif instruction.get('action') == 'publish':
@ -373,7 +385,8 @@ class FeishuBot:
'image_count': 1, 'image_count': 1,
'image_model': None, 'image_model': None,
'image_size': None, 'image_size': None,
'image_style': None 'image_style': None,
'image_format': None
} }
lines = content.strip().split('\n') lines = content.strip().split('\n')
@ -421,10 +434,18 @@ class FeishuBot:
instruction['image_model'] = model instruction['image_model'] = model
elif line.startswith('#生图尺寸') or line.startswith('#图片尺寸'): elif line.startswith('#生图尺寸') or line.startswith('#图片尺寸'):
size = line.replace('#生图尺寸', '').replace('#图片尺寸', '').strip() size = line.replace('#生图尺寸', '').replace('#图片尺寸', '').strip()
# 支持快捷方式
if size in SIZE_PRESETS:
instruction['image_size'] = SIZE_PRESETS[size]
else:
instruction['image_size'] = size instruction['image_size'] = size
elif line.startswith('#生图风格') or line.startswith('#图片风格'): elif line.startswith('#生图风格') or line.startswith('#图片风格'):
style = line.replace('#生图风格', '').replace('#图片风格', '').strip() style = line.replace('#生图风格', '').replace('#图片风格', '').strip()
instruction['image_style'] = style instruction['image_style'] = style
elif line.startswith('#生图格式') or line.startswith('#图片格式'):
fmt = line.replace('#生图格式', '').replace('#图片格式', '').strip().lower()
if fmt in ['jpg', 'png', 'webp']:
instruction['image_format'] = fmt
# 发布+生图指令 # 发布+生图指令
elif line.startswith('#发布并生图') or line.startswith('#发布+生图'): elif line.startswith('#发布并生图') or line.startswith('#发布+生图'):
instruction['action'] = 'publish_with_image' instruction['action'] = 'publish_with_image'
@ -530,7 +551,7 @@ class FeishuBot:
return f"❌ 发布失败:{str(e)}" return f"❌ 发布失败:{str(e)}"
def _publish_with_generated_image(self, text='', title='', category='', tags='', status='publish', def _publish_with_generated_image(self, text='', title='', category='', tags='', status='publish',
image_count=1, model=None, size=None, style=None): image_count=1, model=None, size=None, style=None, image_format=None):
""" """
发布文章并自动生成配图 发布文章并自动生成配图
@ -544,6 +565,7 @@ class FeishuBot:
model: 生图模型 model: 生图模型
size: 图片尺寸 size: 图片尺寸
style: 图片风格 style: 图片风格
image_format: 图片格式
Returns: Returns:
str: 回复消息 str: 回复消息
@ -570,7 +592,8 @@ class FeishuBot:
title=title or '自动提取', title=title or '自动提取',
content=text, content=text,
count=image_count, count=image_count,
api_key=config.get('dashscope_api_key') api_key=config.get('dashscope_api_key'),
image_format=image_format
) )
if not image_result.get('success'): if not image_result.get('success'):
@ -613,7 +636,7 @@ class FeishuBot:
logger.error(f"发布文章(含 AI 配图)失败:{str(e)}", exc_info=True) logger.error(f"发布文章(含 AI 配图)失败:{str(e)}", exc_info=True)
return f"❌ 发布失败:{str(e)}" return f"❌ 发布失败:{str(e)}"
def _generate_image(self, prompt='', count=1, model=None, size=None, style=None): def _generate_image(self, prompt='', count=1, model=None, size=None, style=None, image_format=None):
""" """
生成 AI 图片 生成 AI 图片
@ -623,6 +646,7 @@ class FeishuBot:
model: 模型名称 model: 模型名称
size: 图片尺寸 size: 图片尺寸
style: 图片风格 style: 图片风格
image_format: 图片格式
Returns: Returns:
str: 回复消息 str: 回复消息
@ -648,14 +672,16 @@ class FeishuBot:
model=model, model=model,
size=size, size=size,
count=count, count=count,
style=style style=style,
image_format=image_format
) )
if result.get('success'): if result.get('success'):
paths = result.get('paths', []) paths = result.get('paths', [])
reply = f"✅ AI 生图完成!成功生成 {len(paths)} 张图片\n" reply = f"✅ AI 生图完成!成功生成 {len(paths)} 张图片\n"
reply += f"📊 模型:{result.get('model', 'wanx-v1')}\n" reply += f"📊 模型:{result.get('model', 'wanx-v1')}\n"
reply += f"📐 尺寸:{result.get('size', '1024*1024')}\n\n" reply += f"📐 尺寸:{result.get('size', '1024*1024')}\n"
reply += f"🖼️ 格式:{result.get('format', 'webp')}\n\n"
reply += "📁 本地路径:\n" reply += "📁 本地路径:\n"
for i, path in enumerate(paths): for i, path in enumerate(paths):
reply += f" {i+1}. {path}\n" reply += f" {i+1}. {path}\n"
@ -675,6 +701,7 @@ class FeishuBot:
'dashscope_api_key': '', 'dashscope_api_key': '',
'image_model': 'wanx-v1', 'image_model': 'wanx-v1',
'image_size': '1024*1024', 'image_size': '1024*1024',
'image_format': 'webp',
'image_count': 1 'image_count': 1
} }
@ -791,7 +818,7 @@ class FeishuBot:
🖼 **发布图片文章** 🖼 **发布图片文章**
发送图片即可发布 发送图片即可发布
🎨 **AI 图片生成**新增 🎨 **AI 图片生成**支持格式控制
使用 AI 生成文章配图或独立图片 使用 AI 生成文章配图或独立图片
--- ---
@ -807,15 +834,24 @@ class FeishuBot:
--- ---
**AI 生图指令**新增 **AI 生图指令**
`#生图 图片描述` - 生成指定描述的图片 `#生图 图片描述` - 生成指定描述的图片
`#生图数量 2` - 设置生成数量1-4 `#生图数量 2` - 设置生成数量1-4
`#生图模型 wanx-v1` - 选择模型 `#生图模型 wanx-v1` - 选择模型
`#生图尺寸 1024*1024` - 设置尺寸 `#生图尺寸 1024*1024` - 设置尺寸(支持快捷方式)
`#生图风格 写实` - 设置风格 `#生图风格 写实` - 设置风格
`#生图格式 webp` - 设置格式webp, jpg, png
**发布+生图指令**新增 **尺寸快捷方式**
- 正方形 1024*1024
- 横图 1280*720
- 竖图 720*1280
- 宽屏 1440*720
- 手机 720*1440
- 小图 512*512
**发布+生图指令**
`#发布并生图` - 发布文章并自动生成配图 `#发布并生图` - 发布文章并自动生成配图
#标题、#分类 等指令配合使用) #标题、#分类 等指令配合使用)
@ -835,7 +871,8 @@ class FeishuBot:
``` ```
#生图 一只可爱的猫咪在草地上晒太阳,高质量插画 #生图 一只可爱的猫咪在草地上晒太阳,高质量插画
#生图数量 2 #生图数量 2
#生图尺寸 1024*1024 #生图尺寸 横图
#生图格式 webp
``` ```
**发布+生图示例** **发布+生图示例**
@ -875,7 +912,7 @@ class FeishuBot:
- **状态** 运行中 - **状态** 运行中
- **WordPress**https://www.nanlou.net - **WordPress**https://www.nanlou.net
- **发布脚本**已就绪 - **发布脚本**已就绪
- **AI 生图** 支持 - **AI 生图** 支持webp/jpg/png
发送 `#帮助` 查看使用说明""" 发送 `#帮助` 查看使用说明"""

View File

@ -3,7 +3,8 @@
""" """
WordPress 发布系统 - AI 图片生成模块 WordPress 发布系统 - AI 图片生成模块
基于阿里云 DashScope API 实现文生图功能 基于阿里云 DashScope API 实现文生图功能
支持通义万相 (wanx-v1) 支持通义万相 (wanx-v1, wanx2.1-t2i-turbo, wanx2.1-t2i-plus)
支持格式jpg, png, webp
""" """
import os import os
@ -34,21 +35,37 @@ class ImageGenerator:
'wanx2.1-t2i-turbo': { 'wanx2.1-t2i-turbo': {
'name': '通义万相 v2 Turbo', 'name': '通义万相 v2 Turbo',
'base_url': 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis', 'base_url': 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis',
'sizes': ['1024*1024', '720*1280', '1280*720', '512*512'], 'sizes': ['1024*1024', '720*1280', '1280*720', '512*512', '1440*720', '720*1440'],
'max_images': 4 'max_images': 4
}, },
'wanx2.1-t2i-plus': { 'wanx2.1-t2i-plus': {
'name': '通义万相 v2 Plus', 'name': '通义万相 v2 Plus',
'base_url': 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis', 'base_url': 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis',
'sizes': ['1024*1024', '720*1280', '1280*720', '512*512'], 'sizes': ['1024*1024', '720*1280', '1280*720', '512*512', '1440*720', '720*1440'],
'max_images': 4 'max_images': 4
} }
} }
# 支持的图片格式
SUPPORTED_FORMATS = ['jpg', 'png', 'webp']
# 默认尺寸 # 默认尺寸
DEFAULT_SIZE = '1024*1024' DEFAULT_SIZE = '1024*1024'
def __init__(self, api_key=None, model='wanx-v1', size=None): # 默认格式
DEFAULT_FORMAT = 'webp'
# 尺寸快捷方式
SIZE_PRESETS = {
'正方形': '1024*1024',
'横图': '1280*720',
'竖图': '720*1280',
'宽屏': '1440*720',
'手机': '720*1440',
'小图': '512*512'
}
def __init__(self, api_key=None, model='wanx-v1', size=None, image_format=None):
""" """
初始化图片生成器 初始化图片生成器
@ -56,16 +73,22 @@ class ImageGenerator:
api_key: DashScope API Key api_key: DashScope API Key
model: 模型名称 model: 模型名称
size: 图片尺寸 size: 图片尺寸
image_format: 图片格式 (jpg, png, webp)
""" """
self.api_key = api_key or self._get_api_key_from_env() self.api_key = api_key or self._get_api_key_from_env()
self.model = model if model in self.SUPPORTED_MODELS else 'wanx-v1' self.model = model if model in self.SUPPORTED_MODELS else 'wanx-v1'
self.size = size or self.DEFAULT_SIZE self.size = size or self.DEFAULT_SIZE
self.image_format = image_format or self.DEFAULT_FORMAT
# 验证尺寸 # 验证尺寸
model_config = self.SUPPORTED_MODELS[self.model] model_config = self.SUPPORTED_MODELS[self.model]
if self.size not in model_config['sizes']: if self.size not in model_config['sizes']:
self.size = self.DEFAULT_SIZE self.size = self.DEFAULT_SIZE
# 验证格式
if self.image_format not in self.SUPPORTED_FORMATS:
self.image_format = self.DEFAULT_FORMAT
self.base_url = model_config['base_url'] self.base_url = model_config['base_url']
self.max_images = model_config['max_images'] self.max_images = model_config['max_images']
@ -88,8 +111,8 @@ class ImageGenerator:
if n < 1 or n > self.max_images: if n < 1 or n > self.max_images:
n = 1 n = 1
self.pl.info(f"🎨 AI 生图开始 - 模型:{self.model}, 尺寸:{self.size}, 数量:{n}") self.pl.info(f"🎨 AI 生图开始 - 模型:{self.model}, 尺寸:{self.size}, 格式:{self.image_format}, 数量:{n}")
self.dl.log_step("AI 生图", f"模型:{self.model}, 尺寸:{self.size}") self.dl.log_step("AI 生图", f"模型:{self.model}, 尺寸:{self.size}, 格式:{self.image_format}")
self.dl.debug(f"提示词:{prompt}") self.dl.debug(f"提示词:{prompt}")
if negative_prompt: if negative_prompt:
self.dl.debug(f"反向提示词:{negative_prompt}") self.dl.debug(f"反向提示词:{negative_prompt}")
@ -107,12 +130,13 @@ class ImageGenerator:
self.pl.error("生图任务失败:未获取到图片 URL") self.pl.error("生图任务失败:未获取到图片 URL")
return [] return []
# 下载图片到本地 # 下载图片到本地(转换为指定格式)
local_paths = self._download_images(image_urls, prompt) local_paths = self._download_images(image_urls, prompt)
self.pl.success(f"AI 生图完成 - 成功 {len(local_paths)} 张图片") self.pl.success(f"AI 生图完成 - 成功 {len(local_paths)} 张图片")
self.dl.log_result("生图结果", { self.dl.log_result("生图结果", {
'model': self.model, 'model': self.model,
'format': self.image_format,
'count': len(local_paths), 'count': len(local_paths),
'paths': local_paths 'paths': local_paths
}) })
@ -252,7 +276,7 @@ class ImageGenerator:
return [] return []
def _download_images(self, image_urls, prompt): def _download_images(self, image_urls, prompt):
"""下载图片到本地""" """下载图片到本地并转换为指定格式"""
local_paths = [] local_paths = []
for i, url in enumerate(image_urls): for i, url in enumerate(image_urls):
@ -260,19 +284,14 @@ class ImageGenerator:
response = requests.get(url, timeout=30) response = requests.get(url, timeout=30)
if response.status_code == 200: if response.status_code == 200:
# 生成文件名 # 使用 PIL 进行格式转换
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') local_path = self._convert_and_save_image(
prompt_hash = abs(hash(prompt)) % 10000 response.content,
filename = f"ai_image_{timestamp}_{i+1}_{prompt_hash}.png" prompt,
filepath = os.path.join(IMAGE_DIR, filename) i + 1
)
with open(filepath, 'wb') as f: if local_path:
f.write(response.content) local_paths.append(local_path)
file_size = os.path.getsize(filepath)
local_paths.append(filepath)
self.dl.debug(f"图片已保存:{filepath} ({file_size} 字节)")
else: else:
self.pl.error(f"下载图片失败:{url} (状态码:{response.status_code})") self.pl.error(f"下载图片失败:{url} (状态码:{response.status_code})")
@ -281,6 +300,68 @@ class ImageGenerator:
return local_paths return local_paths
def _convert_and_save_image(self, image_data, prompt, index):
"""
将图片数据转换格式并保存
Args:
image_data: 图片二进制数据
prompt: 提示词用于生成文件名
index: 图片索引
Returns:
str: 保存的文件路径
"""
try:
from PIL import Image
from io import BytesIO
# 打开图片
img = Image.open(BytesIO(image_data))
# 确保是 RGB 模式webp 不支持 RGBA
if img.mode == 'RGBA':
# 创建白色背景
background = Image.new('RGB', img.size, (255, 255, 255))
background.paste(img, mask=img.split()[3]) # 使用 alpha 通道作为 mask
img = background
elif img.mode != 'RGB':
img = img.convert('RGB')
# 生成文件名
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
prompt_hash = abs(hash(prompt)) % 10000
ext = self.image_format if self.image_format == 'jpg' else self.image_format
filename = f"ai_image_{timestamp}_{index}_{prompt_hash}.{ext}"
filepath = os.path.join(IMAGE_DIR, filename)
# 保存图片
if self.image_format == 'webp':
img.save(filepath, 'WEBP', quality=85)
elif self.image_format == 'jpg':
img.save(filepath, 'JPEG', quality=95)
elif self.image_format == 'png':
img.save(filepath, 'PNG')
file_size = os.path.getsize(filepath)
self.dl.debug(f"图片已保存:{filepath} ({file_size} 字节, 格式:{self.image_format})")
return filepath
except ImportError:
self.pl.error("PIL 未安装,无法转换图片格式,保存原始图片")
# 降级:保存原始图片
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
prompt_hash = abs(hash(prompt)) % 10000
filename = f"ai_image_{timestamp}_{index}_{prompt_hash}.png"
filepath = os.path.join(IMAGE_DIR, filename)
with open(filepath, 'wb') as f:
f.write(image_data)
return filepath
except Exception as e:
self.pl.error(f"转换图片格式失败:{str(e)}")
return None
def _get_api_key_from_env(self): def _get_api_key_from_env(self):
"""从环境变量获取 API Key""" """从环境变量获取 API Key"""
return os.environ.get('DASHSCOPE_API_KEY', '') return os.environ.get('DASHSCOPE_API_KEY', '')
@ -295,18 +376,26 @@ class ImageGenerator:
return self.SUPPORTED_MODELS.get(model, {}) return self.SUPPORTED_MODELS.get(model, {})
return self.SUPPORTED_MODELS return self.SUPPORTED_MODELS
def get_supported_formats(self):
"""获取支持的格式列表"""
return self.SUPPORTED_FORMATS
def create_image_generator(api_key=None, model='wanx-v1', size=None): def get_size_presets(self):
"""获取尺寸快捷方式"""
return self.SIZE_PRESETS
def create_image_generator(api_key=None, model='wanx-v1', size=None, image_format=None):
"""创建图片生成器实例""" """创建图片生成器实例"""
return ImageGenerator(api_key=api_key, model=model, size=size) return ImageGenerator(api_key=api_key, model=model, size=size, image_format=image_format)
if __name__ == '__main__': if __name__ == '__main__':
import sys import sys
if len(sys.argv) < 3: if len(sys.argv) < 3:
print("用法python wp_image_generator.py <api_key> <prompt> [model] [size] [count]") print("用法python wp_image_generator.py <api_key> <prompt> [model] [size] [count] [format]")
print("示例python wp_image_generator.py sk-xxx '一只可爱的猫咪' wanx-v1 1024*1024 1") print("示例python wp_image_generator.py sk-xxx '一只可爱的猫咪' wanx-v1 1024*1024 1 webp")
sys.exit(1) sys.exit(1)
api_key = sys.argv[1] api_key = sys.argv[1]
@ -314,8 +403,9 @@ if __name__ == '__main__':
model = sys.argv[3] if len(sys.argv) > 3 else 'wanx-v1' model = sys.argv[3] if len(sys.argv) > 3 else 'wanx-v1'
size = sys.argv[4] if len(sys.argv) > 4 else '1024*1024' size = sys.argv[4] if len(sys.argv) > 4 else '1024*1024'
count = int(sys.argv[5]) if len(sys.argv) > 5 else 1 count = int(sys.argv[5]) if len(sys.argv) > 5 else 1
image_format = sys.argv[6] if len(sys.argv) > 6 else 'webp'
generator = create_image_generator(api_key=api_key, model=model, size=size) generator = create_image_generator(api_key=api_key, model=model, size=size, image_format=image_format)
paths = generator.generate_image(prompt, n=count) paths = generator.generate_image(prompt, n=count)
print(f"\n生成结果:") print(f"\n生成结果:")

View File

@ -3,6 +3,7 @@
""" """
WordPress 发布系统 - AI 图片生成脚本 WordPress 发布系统 - AI 图片生成脚本
支持命令行调用和模块调用 支持命令行调用和模块调用
支持格式控制jpg, png, webp
""" """
import os import os
@ -24,6 +25,7 @@ def load_config():
'dashscope_api_key': '', 'dashscope_api_key': '',
'image_model': 'wanx-v1', 'image_model': 'wanx-v1',
'image_size': '1024*1024', 'image_size': '1024*1024',
'image_format': 'webp',
'image_count': 1, 'image_count': 1,
'image_style': None 'image_style': None
} }
@ -40,7 +42,7 @@ def load_config():
def generate_image(prompt, api_key=None, model=None, size=None, count=None, def generate_image(prompt, api_key=None, model=None, size=None, count=None,
negative_prompt=None, style=None): negative_prompt=None, style=None, image_format=None):
""" """
生成图片主入口函数 生成图片主入口函数
@ -52,6 +54,7 @@ def generate_image(prompt, api_key=None, model=None, size=None, count=None,
count: 生成数量可选 count: 生成数量可选
negative_prompt: 反向提示词可选 negative_prompt: 反向提示词可选
style: 风格可选 style: 风格可选
image_format: 图片格式 (jpg, png, webp)可选
Returns: Returns:
dict: 生成结果 dict: 生成结果
@ -68,6 +71,7 @@ def generate_image(prompt, api_key=None, model=None, size=None, count=None,
size = size or config.get('image_size', '1024*1024') size = size or config.get('image_size', '1024*1024')
count = count or config.get('image_count', 1) count = count or config.get('image_count', 1)
style = style or config.get('image_style', None) style = style or config.get('image_style', None)
image_format = image_format or config.get('image_format', 'webp')
if not api_key: if not api_key:
pl.error("未配置 DashScope API Key") pl.error("未配置 DashScope API Key")
@ -80,7 +84,8 @@ def generate_image(prompt, api_key=None, model=None, size=None, count=None,
generator = create_image_generator( generator = create_image_generator(
api_key=api_key, api_key=api_key,
model=model, model=model,
size=size size=size,
image_format=image_format
) )
# 生成图片 # 生成图片
@ -98,7 +103,8 @@ def generate_image(prompt, api_key=None, model=None, size=None, count=None,
'count': len(image_paths), 'count': len(image_paths),
'paths': image_paths, 'paths': image_paths,
'model': model, 'model': model,
'size': size 'size': size,
'format': image_format
} }
else: else:
pl.end_publish(False, error_msg='生成图片失败') pl.end_publish(False, error_msg='生成图片失败')
@ -116,7 +122,7 @@ def generate_image(prompt, api_key=None, model=None, size=None, count=None,
} }
def generate_images_for_article(title, content, count=1, api_key=None): def generate_images_for_article(title, content, count=1, api_key=None, image_format='webp'):
""" """
根据文章标题和内容生成配图 根据文章标题和内容生成配图
@ -125,6 +131,7 @@ def generate_images_for_article(title, content, count=1, api_key=None):
content: 文章内容 content: 文章内容
count: 生成数量 count: 生成数量
api_key: DashScope API Key可选 api_key: DashScope API Key可选
image_format: 图片格式 (jpg, png, webp)
Returns: Returns:
dict: 生成结果 dict: 生成结果
@ -135,6 +142,7 @@ def generate_images_for_article(title, content, count=1, api_key=None):
# 加载配置 # 加载配置
config = load_config() config = load_config()
api_key = api_key or config.get('dashscope_api_key', '') api_key = api_key or config.get('dashscope_api_key', '')
image_format = image_format or config.get('image_format', 'webp')
if not api_key: if not api_key:
pl.error("未配置 DashScope API Key") pl.error("未配置 DashScope API Key")
@ -152,7 +160,8 @@ def generate_images_for_article(title, content, count=1, api_key=None):
result = generate_image( result = generate_image(
prompt=prompt, prompt=prompt,
api_key=api_key, api_key=api_key,
count=count count=count,
image_format=image_format
) )
return result return result
@ -164,6 +173,7 @@ def main():
parser.add_argument('prompt', help='图片描述') parser.add_argument('prompt', help='图片描述')
parser.add_argument('--model', '-m', default=None, help='模型名称 (wanx-v1, wanx2.1-t2i-turbo, wanx2.1-t2i-plus)') parser.add_argument('--model', '-m', default=None, help='模型名称 (wanx-v1, wanx2.1-t2i-turbo, wanx2.1-t2i-plus)')
parser.add_argument('--size', '-s', default=None, help='图片尺寸 (1024*1024, 720*1280, 1280*720 等)') parser.add_argument('--size', '-s', default=None, help='图片尺寸 (1024*1024, 720*1280, 1280*720 等)')
parser.add_argument('--format', '-f', default=None, choices=['jpg', 'png', 'webp'], help='图片格式 (jpg, png, webp)')
parser.add_argument('--count', '-n', type=int, default=None, help='生成数量 (1-4)') parser.add_argument('--count', '-n', type=int, default=None, help='生成数量 (1-4)')
parser.add_argument('--style', default=None, help='图片风格 (写实、动漫、水彩等)') parser.add_argument('--style', default=None, help='图片风格 (写实、动漫、水彩等)')
parser.add_argument('--negative', default=None, help='反向提示词') parser.add_argument('--negative', default=None, help='反向提示词')
@ -178,7 +188,8 @@ def main():
size=args.size, size=args.size,
count=args.count, count=args.count,
negative_prompt=args.negative, negative_prompt=args.negative,
style=args.style style=args.style,
image_format=args.format
) )
# 输出 JSON 结果 # 输出 JSON 结果