update
This commit is contained in:
		@@ -37,4 +37,4 @@ const loopGetStatus = async (taskId: string) => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// main()
 | 
					// main()
 | 
				
			||||||
loopGetStatus(id);
 | 
					// loopGetStatus(id);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										41
									
								
								mock/qwen/01.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								mock/qwen/01.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					import dotenv from 'dotenv';
 | 
				
			||||||
 | 
					import util from 'node:util';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dotenv.config({ path: '.env' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { QwenText2Image } from '../../src/dashscope/dashscope.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const main = async () => {
 | 
				
			||||||
 | 
					  // 1. create image
 | 
				
			||||||
 | 
					  const qwen = new QwenText2Image(process.env.BAILIAN_API_KEY || '');
 | 
				
			||||||
 | 
					  const res = await qwen.queryImage({
 | 
				
			||||||
 | 
					    model: 'wan2.2-t2i-flash',
 | 
				
			||||||
 | 
					    input: {
 | 
				
			||||||
 | 
					      prompt: '一个可爱的小的熊猫,卡通风格,抱着竹子。周边有很多彩色的气球。',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  console.log('create image response:', util.inspect(res, { depth: null, colors: true }));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					main()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// create image response: {
 | 
				
			||||||
 | 
					//   request_id: '6b8d3e4d-0b1a-4a01-bcc9-826336e4267a',
 | 
				
			||||||
 | 
					//   output: {
 | 
				
			||||||
 | 
					//     task_id: '3318eb1d-cd5d-4408-a9bb-6cddd7967a43',
 | 
				
			||||||
 | 
					//     task_status: 'SUCCEEDED',
 | 
				
			||||||
 | 
					//     submit_time: '2025-09-15 19:37:22.177',
 | 
				
			||||||
 | 
					//     scheduled_time: '2025-09-15 19:37:22.228',
 | 
				
			||||||
 | 
					//     end_time: '2025-09-15 19:37:28.802',
 | 
				
			||||||
 | 
					//     results: [
 | 
				
			||||||
 | 
					//       {
 | 
				
			||||||
 | 
					//         orig_prompt: '一个可爱的小的熊猫,卡通风格,抱着竹子。周边有很多彩色的气球。',
 | 
				
			||||||
 | 
					//         actual_prompt: '卡通风格的可爱小熊猫,圆润造型,毛茸茸的白色身体与黑色斑纹分明,抱着翠绿竹子,周围漂浮着五彩缤纷的圆形气球,背景为浅蓝色天空与几缕白云,画面明亮温馨,适合儿童插画,采用柔和线条与饱满色彩,仰视视角增强萌态。',
 | 
				
			||||||
 | 
					//         url: 'https://dashscope-result-wlcb-acdr-1.oss-cn-wulanchabu-acdr-1.aliyuncs.com/1d/2d/20250915/5020e443/3318eb1d-cd5d-4408-a9bb-6cddd7967a432353322002.png?Expires=1758022648&OSSAccessKeyId=LTAI5tKPD3TMqf2Lna1fASuh&Signature=8EkJ7ccUsKlZHfU6y3Iiog3fjSQ%3D'
 | 
				
			||||||
 | 
					//       }
 | 
				
			||||||
 | 
					//     ],
 | 
				
			||||||
 | 
					//     task_metrics: { TOTAL: 1, SUCCEEDED: 1, FAILED: 0 }
 | 
				
			||||||
 | 
					//   },
 | 
				
			||||||
 | 
					//   usage: { image_count: 1 }
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
							
								
								
									
										24
									
								
								mock/volces.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								mock/volces.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					import dotenv from 'dotenv';
 | 
				
			||||||
 | 
					import util from 'node:util';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dotenv.config({ path: '.env' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { VolcesImage } from '../src/volces/image.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const main = async () => {
 | 
				
			||||||
 | 
					  const volces = new VolcesImage(process.env.VOLECS_API_KEY || '');
 | 
				
			||||||
 | 
					  const resp = await volces.generateImage({
 | 
				
			||||||
 | 
					    model: 'doubao-seedream-4-0-250828',
 | 
				
			||||||
 | 
					    prompt: '一个可爱的小的熊猫,卡通风格,抱着竹子。旁边有一个卡通的奶牛的毛绒玩具。',
 | 
				
			||||||
 | 
					    sequential_image_generation: 'auto',
 | 
				
			||||||
 | 
					    sequential_image_generation_options: { max_images: 3 },
 | 
				
			||||||
 | 
					    response_format: 'url',
 | 
				
			||||||
 | 
					    size: '2K',
 | 
				
			||||||
 | 
					    stream: false,
 | 
				
			||||||
 | 
					    watermark: false
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  console.log('response:', resp);
 | 
				
			||||||
 | 
					  // console.log(util.inspect(resp, { depth: null, colors: true }));
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					main()
 | 
				
			||||||
@@ -1,3 +1,17 @@
 | 
				
			|||||||
 | 
					export const models = ['wan2.2-t2i-flash', 'wan2.2-t2i-plus', 'wanx2.1-t2i-turbo', 'wanx2.1-t2i-plus', 'wanx2.0-t2i-turbo'] as const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type ImageModel = (typeof models)[number];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const sizes = [
 | 
				
			||||||
 | 
					  '1664x928', // 16:9
 | 
				
			||||||
 | 
					  '1472x1140', // 4:3
 | 
				
			||||||
 | 
					  '1328x1328', // 1:1
 | 
				
			||||||
 | 
					  '1140x1472', // 3:4
 | 
				
			||||||
 | 
					  '928x1664', // 9:16
 | 
				
			||||||
 | 
					] as const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type ImageSize = (typeof sizes)[number];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class QwenText2Image {
 | 
					export class QwenText2Image {
 | 
				
			||||||
  text2imageApi = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis';
 | 
					  text2imageApi = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis';
 | 
				
			||||||
  tasksApi = 'https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}';
 | 
					  tasksApi = 'https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}';
 | 
				
			||||||
@@ -7,6 +21,10 @@ export class QwenText2Image {
 | 
				
			|||||||
    this.apiKey = apiKey;
 | 
					    this.apiKey = apiKey;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  async createImage(data: CreateImageRequest): Promise<CreateImageResponse> {
 | 
					  async createImage(data: CreateImageRequest): Promise<CreateImageResponse> {
 | 
				
			||||||
 | 
					    const parameters = data.parameters || {} as CreateImageRequest['parameters'];
 | 
				
			||||||
 | 
					    if (parameters!.n === undefined) {
 | 
				
			||||||
 | 
					      parameters!.n = 1; // 默认生成1张图片
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    const res = await fetch(this.text2imageApi, {
 | 
					    const res = await fetch(this.text2imageApi, {
 | 
				
			||||||
      method: 'POST',
 | 
					      method: 'POST',
 | 
				
			||||||
      headers: {
 | 
					      headers: {
 | 
				
			||||||
@@ -14,7 +32,7 @@ export class QwenText2Image {
 | 
				
			|||||||
        'X-DashScope-Async': 'enable',
 | 
					        'X-DashScope-Async': 'enable',
 | 
				
			||||||
        Authorization: `Bearer ${this.apiKey}`,
 | 
					        Authorization: `Bearer ${this.apiKey}`,
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      body: JSON.stringify(data),
 | 
					      body: JSON.stringify({ ...data, parameters }),
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    return await res.json();
 | 
					    return await res.json();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -40,6 +58,21 @@ export class QwenText2Image {
 | 
				
			|||||||
    this.taskResponse = await res.json();
 | 
					    this.taskResponse = await res.json();
 | 
				
			||||||
    return this.taskResponse;
 | 
					    return this.taskResponse;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  async queryImage(data: CreateImageRequest): Promise<TaskResponse> {
 | 
				
			||||||
 | 
					    const image = await this.createImage(data);
 | 
				
			||||||
 | 
					    const taskId = image.output.task_id;
 | 
				
			||||||
 | 
					    let status: string;
 | 
				
			||||||
 | 
					    do {
 | 
				
			||||||
 | 
					      await this.getTaskStatus(taskId);
 | 
				
			||||||
 | 
					      status = this.taskResponse?.output?.task_status;
 | 
				
			||||||
 | 
					      if (status === 'SUCCEEDED') {
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      await new Promise((resolve) => setTimeout(resolve, 1000));
 | 
				
			||||||
 | 
					    } while (status !== 'SUCCEEDED' && status !== 'FAILED');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return this.taskResponse;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type TaskStatus = 'PENDING' | 'SUCCESS' | 'FAILURE' | 'CANCELED' | 'UNKNOWN';
 | 
					type TaskStatus = 'PENDING' | 'SUCCESS' | 'FAILURE' | 'CANCELED' | 'UNKNOWN';
 | 
				
			||||||
@@ -99,16 +132,3 @@ type TaskResponse = {
 | 
				
			|||||||
  message?: string;
 | 
					  message?: string;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const models = ['wan2.2-t2i-flash', 'wan2.2-t2i-plus', 'wanx2.1-t2i-turbo', 'wanx2.1-t2i-plus', 'wanx2.0-t2i-turbo'] as const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export type ImageModel = (typeof models)[number];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const sizes = [
 | 
					 | 
				
			||||||
  '1664x928', // 16:9
 | 
					 | 
				
			||||||
  '1472x1140', // 4:3
 | 
					 | 
				
			||||||
  '1328x1328', // 1:1
 | 
					 | 
				
			||||||
  '1140x1472', // 3:4
 | 
					 | 
				
			||||||
  '928x1664', // 9:16
 | 
					 | 
				
			||||||
] as const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export type ImageSize = (typeof sizes)[number];
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										45
									
								
								src/volces/image.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/volces/image.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					export class VolcesImage {
 | 
				
			||||||
 | 
					  apiUrl = 'https://ark.cn-beijing.volces.com/api/v3/images/generations';
 | 
				
			||||||
 | 
					  apiKey: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor(apiKey: string) {
 | 
				
			||||||
 | 
					    this.apiKey = apiKey;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async generateImage(data: VolcesImageRequest): Promise<VolcesImageResponse> {
 | 
				
			||||||
 | 
					    const res = await fetch(this.apiUrl, {
 | 
				
			||||||
 | 
					      method: 'POST',
 | 
				
			||||||
 | 
					      headers: {
 | 
				
			||||||
 | 
					        'Content-Type': 'application/json',
 | 
				
			||||||
 | 
					        Authorization: `Bearer ${this.apiKey}`,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      body: JSON.stringify(data),
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return await res.json();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type VolcesImageRequest = {
 | 
				
			||||||
 | 
					  model: string;
 | 
				
			||||||
 | 
					  prompt: string;
 | 
				
			||||||
 | 
					  image?: string[]; // 输入图片数组
 | 
				
			||||||
 | 
					  sequential_image_generation?: 'auto' | 'manual';
 | 
				
			||||||
 | 
					  sequential_image_generation_options?: {
 | 
				
			||||||
 | 
					    max_images?: number;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  response_format?: 'url' | 'base64';
 | 
				
			||||||
 | 
					  size?: string; // 如 "2K"
 | 
				
			||||||
 | 
					  stream?: boolean;
 | 
				
			||||||
 | 
					  watermark?: boolean;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type VolcesImageResponse = {
 | 
				
			||||||
 | 
					  id: string;
 | 
				
			||||||
 | 
					  object: string;
 | 
				
			||||||
 | 
					  created: number;
 | 
				
			||||||
 | 
					  urls?: string[]; // 当 response_format 为 url
 | 
				
			||||||
 | 
					  images?: string[]; // 当 response_format 为 base64
 | 
				
			||||||
 | 
					  status: string;
 | 
				
			||||||
 | 
					  message?: string;
 | 
				
			||||||
 | 
					  [key: string]: any;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
		Reference in New Issue
	
	Block a user