新方案v1角色结构理解
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import path from 'node:path';
|
||||
import {imageFormat} from '../lib/images.mjs';
|
||||
import {requestJson, downloadImage} from './http.mjs';
|
||||
|
||||
export function validateEditInputs(stage, images, mask) {
|
||||
if (!images.length) throw new Error('图片编辑至少需要一张输入图');
|
||||
if (images.length > 1 && !stage.capabilities.multiple_images) throw new Error('尚未确认此提供方支持多图;请先验证再启用 capabilities.multiple_images');
|
||||
if (mask) {
|
||||
if (!stage.capabilities.mask) throw new Error('尚未确认此提供方支持编辑掩码;不能静默忽略 --mask');
|
||||
if (stage.maskEditable !== 'transparent') throw new Error('当前掩码适配仅支持透明像素为可编辑区域');
|
||||
if (mask.extension !== 'png' || mask.width !== images[0].width || mask.height !== images[0].height) {
|
||||
throw new Error('编辑 mask 必须为与第一张输入图同尺寸的 PNG');
|
||||
}
|
||||
if (![4, 6].includes(mask.bytes[25])) throw new Error('编辑 mask 必须包含 alpha 通道(透明处允许编辑),不能直接传 SAM 黑白掩码');
|
||||
}
|
||||
}
|
||||
|
||||
export async function editImage(stage, {images, mask, prompt}, options) {
|
||||
validateEditInputs(stage, images, mask);
|
||||
return requestJson(stage, 'images/edits', () => {
|
||||
const form = new FormData();
|
||||
form.append('model', stage.model);
|
||||
form.append('prompt', prompt);
|
||||
for (const [name, value] of Object.entries(stage.params)) {
|
||||
if (value !== null && value !== undefined) form.append(name, typeof value === 'object' ? JSON.stringify(value) : String(value));
|
||||
}
|
||||
for (const image of images) form.append(stage.imageField, new Blob([image.bytes], {type: image.mime}), path.basename(image.file));
|
||||
if (mask) form.append('mask', new Blob([mask.bytes], {type: mask.mime}), path.basename(mask.file));
|
||||
return {method: 'POST', body: form};
|
||||
}, options);
|
||||
}
|
||||
|
||||
export async function decodeEditedImages(payload, stage, {fetchImpl = fetch} = {}) {
|
||||
const items = payload.data || payload.images || payload.output;
|
||||
if (!Array.isArray(items) || !items.length) throw new Error('图片编辑响应没有图片列表');
|
||||
const decoded = [];
|
||||
for (const item of items) {
|
||||
let bytes;
|
||||
if (typeof item.b64_json === 'string') bytes = Buffer.from(item.b64_json, 'base64');
|
||||
else if (typeof item.url === 'string') bytes = await downloadImage(item.url, stage, fetchImpl);
|
||||
else throw new Error('图片编辑响应缺少 b64_json/url');
|
||||
decoded.push({bytes, ...imageFormat(bytes)});
|
||||
}
|
||||
return decoded;
|
||||
}
|
||||
Reference in New Issue
Block a user