fix(image): 修复图像生成中quality参数传递问题
- 添加QUALITY_ALIASES映射表支持质量别名 - 实现normalizeQuality函数进行参数归一化 - 在requestGeneration和requestEdit中验证quality参数 - 防止auto或异常值传递给上游API导致400错误 - 更新FormData和POST请求中的quality参数处理逻辑
This commit is contained in:
@@ -1 +1,3 @@
|
|||||||
# 待测试
|
# 待测试
|
||||||
|
|
||||||
|
- 修复生图工作台和画布生图请求中 `quality` 参数可能传入上游不支持值导致 400 的问题;请求前会归一化质量枚举,`auto` 或异常值不再发送给上游。
|
||||||
|
|||||||
@@ -23,7 +23,20 @@ const QUALITY_BASE: Record<string, number> = {
|
|||||||
low: 1024,
|
low: 1024,
|
||||||
medium: 2048,
|
medium: 2048,
|
||||||
high: 2880,
|
high: 2880,
|
||||||
|
standard: 1024,
|
||||||
|
hd: 2048,
|
||||||
};
|
};
|
||||||
|
const QUALITY_ALIASES: Record<string, string> = {
|
||||||
|
"1k": "low",
|
||||||
|
"2k": "medium",
|
||||||
|
"4k": "high",
|
||||||
|
};
|
||||||
|
|
||||||
|
function normalizeQuality(quality: string) {
|
||||||
|
const value = quality.trim().toLowerCase();
|
||||||
|
const normalized = QUALITY_ALIASES[value] || value;
|
||||||
|
return QUALITY_BASE[normalized] ? normalized : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
/** Map "quality + ratio" to an explicit pixel dimension like "3840x2160". Returns undefined when quality is auto. */
|
/** Map "quality + ratio" to an explicit pixel dimension like "3840x2160". Returns undefined when quality is auto. */
|
||||||
function resolveSize(quality: string, ratio: string): string | undefined {
|
function resolveSize(quality: string, ratio: string): string | undefined {
|
||||||
@@ -132,7 +145,8 @@ function withSystemMessage(config: AiConfig, messages: ChatCompletionMessage[])
|
|||||||
|
|
||||||
export async function requestGeneration(config: AiConfig, prompt: string) {
|
export async function requestGeneration(config: AiConfig, prompt: string) {
|
||||||
const n = Math.max(1, Math.min(15, Math.floor(Math.abs(Number(config.count)) || 1)));
|
const n = Math.max(1, Math.min(15, Math.floor(Math.abs(Number(config.count)) || 1)));
|
||||||
const pixelSize = resolveSize(config.quality, config.size);
|
const quality = normalizeQuality(config.quality);
|
||||||
|
const pixelSize = quality ? resolveSize(quality, config.size) : undefined;
|
||||||
try {
|
try {
|
||||||
const response = await axios.post<ImageApiResponse>(
|
const response = await axios.post<ImageApiResponse>(
|
||||||
aiApiUrl(config, "/images/generations"),
|
aiApiUrl(config, "/images/generations"),
|
||||||
@@ -140,7 +154,8 @@ export async function requestGeneration(config: AiConfig, prompt: string) {
|
|||||||
model: config.model,
|
model: config.model,
|
||||||
prompt: withSystemPrompt(config, prompt),
|
prompt: withSystemPrompt(config, prompt),
|
||||||
n,
|
n,
|
||||||
...(pixelSize ? { quality: config.quality, size: pixelSize } : {}),
|
...(quality ? { quality } : {}),
|
||||||
|
...(pixelSize ? { size: pixelSize } : {}),
|
||||||
response_format: "b64_json",
|
response_format: "b64_json",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -157,14 +172,17 @@ export async function requestGeneration(config: AiConfig, prompt: string) {
|
|||||||
|
|
||||||
export async function requestEdit(config: AiConfig, prompt: string, references: ReferenceImage[]) {
|
export async function requestEdit(config: AiConfig, prompt: string, references: ReferenceImage[]) {
|
||||||
const n = Math.max(1, Math.min(15, Math.floor(Math.abs(Number(config.count)) || 1)));
|
const n = Math.max(1, Math.min(15, Math.floor(Math.abs(Number(config.count)) || 1)));
|
||||||
const pixelSize = resolveSize(config.quality, config.size);
|
const quality = normalizeQuality(config.quality);
|
||||||
|
const pixelSize = quality ? resolveSize(quality, config.size) : undefined;
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.set("model", config.model);
|
formData.set("model", config.model);
|
||||||
formData.set("prompt", withSystemPrompt(config, prompt));
|
formData.set("prompt", withSystemPrompt(config, prompt));
|
||||||
formData.set("n", String(n));
|
formData.set("n", String(n));
|
||||||
formData.set("response_format", "b64_json");
|
formData.set("response_format", "b64_json");
|
||||||
|
if (quality) {
|
||||||
|
formData.set("quality", quality);
|
||||||
|
}
|
||||||
if (pixelSize) {
|
if (pixelSize) {
|
||||||
formData.set("quality", config.quality);
|
|
||||||
formData.set("size", pixelSize);
|
formData.set("size", pixelSize);
|
||||||
}
|
}
|
||||||
const files = await Promise.all(references.map(async (image) => dataUrlToFile({ ...image, dataUrl: await imageToDataUrl(image) })));
|
const files = await Promise.all(references.map(async (image) => dataUrlToFile({ ...image, dataUrl: await imageToDataUrl(image) })));
|
||||||
|
|||||||
Reference in New Issue
Block a user