update
This commit is contained in:
		@@ -37,4 +37,4 @@ const loopGetStatus = async (taskId: string) => {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// 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 {
 | 
			
		||||
  text2imageApi = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis';
 | 
			
		||||
  tasksApi = 'https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}';
 | 
			
		||||
@@ -7,6 +21,10 @@ export class QwenText2Image {
 | 
			
		||||
    this.apiKey = apiKey;
 | 
			
		||||
  }
 | 
			
		||||
  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, {
 | 
			
		||||
      method: 'POST',
 | 
			
		||||
      headers: {
 | 
			
		||||
@@ -14,7 +32,7 @@ export class QwenText2Image {
 | 
			
		||||
        'X-DashScope-Async': 'enable',
 | 
			
		||||
        Authorization: `Bearer ${this.apiKey}`,
 | 
			
		||||
      },
 | 
			
		||||
      body: JSON.stringify(data),
 | 
			
		||||
      body: JSON.stringify({ ...data, parameters }),
 | 
			
		||||
    });
 | 
			
		||||
    return await res.json();
 | 
			
		||||
  }
 | 
			
		||||
@@ -40,6 +58,21 @@ export class QwenText2Image {
 | 
			
		||||
    this.taskResponse = await res.json();
 | 
			
		||||
    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';
 | 
			
		||||
@@ -99,16 +132,3 @@ type TaskResponse = {
 | 
			
		||||
  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