import axios from 'axios';
import { iam } from '@volcengine/openapi'
// 接口定义
interface LogoInfo {
add_logo?: boolean; // 是否添加 默认不添加
position?: number; // 0-右下角 1-左下角 2-左上角 3-右上角
language?: number; // 0-中文(AI生成)1-英文(Generated by AI)
opacity?: number; // 0-1 default: 0.3
logo_text_content?: string; // 水印文字内容
}
interface ImageGenerationParams {
prompt: string;
req_key: string; // 取固定值: jimeng_high_aes_general_v21_L
width?: number; // 默认值:512
height?: number; // 默认值:512
seed?: number; // 默认值:-1
use_sr?: boolean; // 文生图+AIGC超分
use_pre_llm?: boolean; // 开启文本扩写,会针对输入prompt进行扩写优化,如果输入prompt较短建议开启,如果输入prompt较长建议关闭
return_url?: boolean; // 输出是否返回图片链接 (链接有效期为24小时)
logo_info?: LogoInfo; // 水印信息
}
interface ImageResponse {
data: {
image_urls: string[]
binary_data_base64: string[]
request_id: string
llm_result: string
infer_ctx: {
algorithm_key: string,
app_key: string,
created_at: string,
generate_id: string,
log_id: string,
params: Record<string, any>,
request_id: string,
session_id: string,
time_stamp: string
},
},
message: string
code: number
time_elapsed: string
}
class JimengApiClient {
// API配置
private readonly API_HOST: string = 'visual.volcengineapi.com';
private readonly API_URL: string = `https://visual.volcengineapi.com`;
private readonly API_VERSION: string = '2022-08-31';
private readonly API_REGION: string = 'cn-north-1';
private readonly API_ACTION: string = 'CVProcess';
private readonly API_SERVICE: string = 'cv';
private readonly SIGN_HEADER: string = 'host;x-date';
private accessKey: string;
private secretKey: string;
private iamService = iam.defaultService
constructor() {
this.accessKey = process.env.VOLCENGINE_ACCESS_KEY || '';
this.secretKey = process.env.VOLCENGINE_SECRET_KEY || '';
this.iamService.setAccessKeyId(this.accessKey)
this.iamService.setSecretKey(this.secretKey)
this.iamService.setRegion(this.API_REGION)
this.iamService.setHost(this.API_HOST)
}
/**
* 验证环境变量是否设置
* @returns 如果环境变量未设置,返回错误消息
*/
private validateCredentials(): string | null {
if (!this.accessKey) {
return 'VOLCENGINE_ACCESS_KEY 环境变量未设置';
}
if (!this.secretKey) {
return 'VOLCENGINE_SECRET_KEY 环境变量未设置';
}
return null;
}
private signStringEncoder(source: string): string {
return encodeURIComponent(source).replace(/[!'()*]/g, function (c) {
return '%' + c.charCodeAt(0).toString(16).toUpperCase();
});
}
/**
* 即梦AI图像生成
* @param params 图像生成参数
* @returns 生成的图像信息
*/
public async generateImage(params: ImageGenerationParams): Promise<any> {
// 验证环境变量
const credentialError = this.validateCredentials();
if (credentialError) {
throw new Error(credentialError);
}
const timestamp = new Date().toISOString().replace(/[-:]|\.\d{3}/g, '');
const requestParams = {
prompt: params.prompt,
req_key: params.req_key || ' jimeng_high_aes_general_v21_L',
...(params.width && { width: params.width.toString() }),
...(params.height && { height: params.height.toString() }),
...(params.seed && { seed: params.seed.toString() }),
...({ use_sr: params.use_sr !== undefined ? Boolean(params.use_sr) : true }),
...({ use_pre_llm: params.use_pre_llm !== undefined ? Boolean(params.use_pre_llm) : true }),
...({ return_url: params.return_url !== undefined ? Boolean(params.return_url) : true }),
...(params.logo_info !== undefined && {
logo_info: JSON.stringify({
AddLogo: params.logo_info.add_logo,
Position: params.logo_info.position,
Language: params.logo_info.language,
Opacity: params.logo_info.opacity,
LogoTextContent: params.logo_info.logo_text_content
})
}),
};
try {
// 发送API请求
const response = await this.iamService.fetchOpenAPI<ImageResponse>({
Action: this.API_ACTION,
Version: this.API_VERSION,
data: requestParams,
method: 'POST',
timeout: 1800000
}, {
serviceName: this.API_SERVICE,
defaultVersion: this.API_VERSION
})
if (response.ResponseMetadata?.Error) {
throw new Error(`${response.ResponseMetadata.Error.Code}: ${response.ResponseMetadata.Error.Message}`)
}
return (response as unknown as ImageResponse).data.image_urls || ''
} catch (error) {
if (axios.isAxiosError(error) && error.response) {
throw new Error(`即梦AI图像生成API错误: ${error.response.data}`)
} else {
throw new Error('即梦AI图像生成请求失败:' + error)
}
}
}
}
const apiClient = new JimengApiClient();
// 导出函数,保持对外接口不变
export const generateImage = (params: ImageGenerationParams) => {
return apiClient.generateImage(params);
};
// 导出接口定义,以便其他模块使用
export type { ImageGenerationParams, LogoInfo };