Skip to content

Commit d69a353

Browse files
committed
refactor: Restructure Aliyun image generation providers
- Move AliWanX21ImageGenerator to new 'aliyun' subdirectory - Add new AliyunWanxPosterGenerator to image generator factory - Update import paths across multiple files - Extend ImageGeneratorType and ImageGeneratorTypeMap to support new poster generator - Modify WeixinArticleWorkflow to use new poster generator with enhanced image generation options
1 parent 266d7d7 commit d69a353

9 files changed

Lines changed: 400 additions & 132 deletions

src/providers/image-gen/aliwanx2.1.image.ts

Lines changed: 0 additions & 123 deletions
This file was deleted.
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
import axios from 'axios';
2+
import { AliTaskResponse, BaseAliyunImageGenerator } from './base.aliyun.image-generator';
3+
4+
/**
5+
* 阿里云海报生成模型参数接口
6+
*/
7+
interface WanxPosterGenOptions {
8+
title: string; // 必选,主标题,最多30个字符
9+
sub_title?: string; // 可选,副标题,最多30个字符
10+
body_text?: string; // 可选,正文,最多50个字符
11+
prompt_text_zh?: string; // 可选,中文提示词
12+
prompt_text_en?: string; // 可选,英文提示词
13+
generate_mode: "generate" | "sr" | "hrf"; // 必选,生成模式
14+
generate_num?: 1 | 2 | 3 | 4; // 可选,生成数量,仅在 generate 模式下有效
15+
auxiliary_parameters?: string; // 可选,sr或hrf模式下的辅助参数
16+
wh_ratios?: "横版" | "竖版"; // 可选,默认横版
17+
lora_name?: "2D插画1" | "2D插画2" | "浩瀚星云" | "浓郁色彩" |
18+
"光线粒子" | "透明玻璃" | "剪纸工艺" | "折纸工艺" |
19+
"中国水墨" | "中国刺绣" | "真实场景" | "2D卡通" |
20+
"儿童水彩" | "赛博背景" | "浅蓝抽象" | "深蓝抽象" |
21+
"抽象点线" | "童话油画"; // 可选,预设背景风格
22+
lora_weight?: number; // 可选,lora权重,范围0-1,默认0.8
23+
ctrl_ratio?: number; // 可选,留白效果权重,范围0-1,默认0.7
24+
ctrl_step?: number; // 可选,留白步数比例,范围0-1,默认0.7
25+
creative_title_layout?: boolean; // 可选,是否启用创意排版,默认false
26+
}
27+
28+
/**
29+
* 阿里云海报生成器实现类
30+
*/
31+
export class AliyunWanxPosterGenerator extends BaseAliyunImageGenerator {
32+
constructor() {
33+
super();
34+
this.baseUrl = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis";
35+
this.model = "wanx-poster-generation-v1";
36+
}
37+
38+
async generate(options: WanxPosterGenOptions): Promise<string> {
39+
// 参数验证
40+
this.validateOptions(options);
41+
42+
try {
43+
// 提交任务
44+
const taskResponse = await this.submitTask<AliTaskResponse>({
45+
input: {
46+
title: options.title,
47+
sub_title: options.sub_title,
48+
body_text: options.body_text,
49+
prompt_text_zh: options.prompt_text_zh,
50+
prompt_text_en: options.prompt_text_en,
51+
generate_mode: options.generate_mode,
52+
generate_num: options.generate_mode === 'generate' ? (options.generate_num || 1) : undefined,
53+
auxiliary_parameters: options.auxiliary_parameters,
54+
lora_name: options.lora_name,
55+
wh_ratios: options.wh_ratios || '横版',
56+
lora_weight: this.clampValue(options.lora_weight, 0, 1, 0.8),
57+
ctrl_ratio: this.clampValue(options.ctrl_ratio, 0, 1, 0.7),
58+
ctrl_step: this.clampValue(options.ctrl_step, 0, 1, 0.7),
59+
creative_title_layout: options.creative_title_layout
60+
},
61+
parameters: {}
62+
});
63+
64+
// 等待任务完成
65+
return await this.waitForCompletion(taskResponse.output.task_id);
66+
} catch (error) {
67+
if (axios.isAxiosError(error)) {
68+
throw new Error(`阿里云API调用失败: ${error.response?.data?.message || error.message}`);
69+
}
70+
throw error;
71+
}
72+
}
73+
74+
private validateOptions(options: WanxPosterGenOptions): void {
75+
if (!options.title) {
76+
throw new Error('标题是必需的');
77+
}
78+
79+
// 裁剪标题
80+
if (options.title.length > 30) {
81+
console.warn(`标题超过30个字符,已自动裁剪。原文: ${options.title}`);
82+
options.title = options.title.slice(0, 30);
83+
}
84+
85+
// 裁剪副标题
86+
if (options.sub_title && options.sub_title.length > 30) {
87+
console.warn(`副标题超过30个字符,已自动裁剪。原文: ${options.sub_title}`);
88+
options.sub_title = options.sub_title.slice(0, 30);
89+
}
90+
91+
// 裁剪正文
92+
if (options.body_text && options.body_text.length > 50) {
93+
console.warn(`正文超过50个字符,已自动裁剪。原文: ${options.body_text}`);
94+
options.body_text = options.body_text.slice(0, 50);
95+
}
96+
97+
// 处理提示词
98+
if (!options.prompt_text_zh && !options.prompt_text_en) {
99+
throw new Error('中文或英文提示词至少需要提供一个');
100+
}
101+
102+
const promptLength = (options.prompt_text_zh?.length || 0) + (options.prompt_text_en?.length || 0);
103+
if (promptLength > 50) {
104+
console.warn('中英文提示词总长度超过50个字符,将按比例裁剪');
105+
if (options.prompt_text_zh && options.prompt_text_en) {
106+
const ratio = 50 / promptLength;
107+
const zhLen = Math.floor(options.prompt_text_zh.length * ratio);
108+
const enLen = Math.floor(options.prompt_text_en.length * ratio);
109+
options.prompt_text_zh = options.prompt_text_zh.slice(0, zhLen);
110+
options.prompt_text_en = options.prompt_text_en.slice(0, enLen);
111+
} else if (options.prompt_text_zh) {
112+
options.prompt_text_zh = options.prompt_text_zh.slice(0, 50);
113+
} else if (options.prompt_text_en) {
114+
options.prompt_text_en = options.prompt_text_en.slice(0, 50);
115+
}
116+
}
117+
118+
// 处理生成模式
119+
if (!['generate', 'sr', 'hrf'].includes(options.generate_mode)) {
120+
console.warn(`生成模式 "${options.generate_mode}" 无效,将使用默认值 "generate"`);
121+
options.generate_mode = 'generate';
122+
}
123+
124+
// 处理sr或hrf模式下的辅助参数
125+
if (options.generate_mode !== 'generate' && !options.auxiliary_parameters) {
126+
console.warn(`${options.generate_mode}模式下需要auxiliary_parameters,将切换为generate模式`);
127+
options.generate_mode = 'generate';
128+
}
129+
130+
// 处理生成数量
131+
if (options.generate_mode === 'generate' && options.generate_num) {
132+
if (![1, 2, 3, 4].includes(options.generate_num)) {
133+
console.warn(`生成数量 ${options.generate_num} 无效,将使用默认值 1`);
134+
options.generate_num = 1;
135+
}
136+
}
137+
138+
// 处理宽高比
139+
if (options.wh_ratios && !['横版', '竖版'].includes(options.wh_ratios)) {
140+
console.warn(`宽高比 "${options.wh_ratios}" 无效,将使用默认值 "横版"`);
141+
options.wh_ratios = '横版';
142+
}
143+
144+
// 处理lora名称
145+
const validLoraNames = [
146+
'2D插画1', '2D插画2', '浩瀚星云', '浓郁色彩', '光线粒子',
147+
'透明玻璃', '剪纸工艺', '折纸工艺', '中国水墨', '中国刺绣',
148+
'真实场景', '2D卡通', '儿童水彩', '赛博背景', '浅蓝抽象',
149+
'深蓝抽象', '抽象点线', '童话油画'
150+
];
151+
152+
if (options.lora_name && !validLoraNames.includes(options.lora_name)) {
153+
console.warn(`lora_name "${options.lora_name}" 无效,将移除此参数`);
154+
delete options.lora_name;
155+
}
156+
157+
// 处理数值范围参数
158+
if (options.lora_weight !== undefined) {
159+
if (options.lora_weight < 0 || options.lora_weight > 1) {
160+
console.warn(`lora_weight ${options.lora_weight} 超出范围[0-1],将使用默认值 0.8`);
161+
options.lora_weight = 0.8;
162+
}
163+
}
164+
165+
if (options.ctrl_ratio !== undefined) {
166+
if (options.ctrl_ratio < 0 || options.ctrl_ratio > 1) {
167+
console.warn(`ctrl_ratio ${options.ctrl_ratio} 超出范围[0-1],将使用默认值 0.7`);
168+
options.ctrl_ratio = 0.7;
169+
}
170+
}
171+
172+
if (options.ctrl_step !== undefined) {
173+
if (options.ctrl_step < 0 || options.ctrl_step > 1) {
174+
console.warn(`ctrl_step ${options.ctrl_step} 超出范围[0-1],将使用默认值 0.7`);
175+
options.ctrl_step = 0.7;
176+
}
177+
}
178+
}
179+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import axios from "axios";
2+
import { AliTaskResponse, BaseAliyunImageGenerator } from "./base.aliyun.image-generator";
3+
4+
export interface AliWanX21Options {
5+
prompt: string;
6+
size?: string;
7+
}
8+
9+
export class AliWanX21ImageGenerator extends BaseAliyunImageGenerator {
10+
constructor() {
11+
super();
12+
this.baseUrl = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis";
13+
this.model = "wanx2.1-t2i-turbo";
14+
}
15+
16+
/**
17+
* 生成图片
18+
* @param options 生成选项
19+
* @returns 图片URL数组
20+
*/
21+
async generate(options: AliWanX21Options): Promise<string> {
22+
const { prompt, size = "1024*1024" } = options;
23+
try {
24+
const response = await this.submitTask<AliTaskResponse>({
25+
input: {
26+
prompt,
27+
size,
28+
},
29+
});
30+
31+
const taskId = response.output.task_id;
32+
return this.waitForCompletion(taskId);
33+
} catch (error) {
34+
if (axios.isAxiosError(error)) {
35+
throw new Error(
36+
`图片生成失败: ${error.response?.data?.message || error.message}`
37+
);
38+
}
39+
throw error;
40+
}
41+
}
42+
}

0 commit comments

Comments
 (0)