fix: stabilize detail replacement result images
This commit is contained in:
parent
537a9d10c2
commit
fa4b4183cf
@ -118,42 +118,48 @@ export async function normalizeReplacementResultImage(params: {
|
||||
const generatedBuffer = await fetchImageBufferFromUrl(params.generatedImageUrl);
|
||||
let targetWidth = params.referenceGeometry?.width;
|
||||
let targetHeight = params.referenceGeometry?.height;
|
||||
|
||||
if (!targetWidth || !targetHeight) {
|
||||
const referenceBuffer = await fetchImageBufferFromUrl(params.referenceImageUrl);
|
||||
const referenceMetadata = await sharp(referenceBuffer, { failOn: "none" })
|
||||
.rotate()
|
||||
.metadata();
|
||||
targetWidth = referenceMetadata.width;
|
||||
targetHeight = referenceMetadata.height;
|
||||
}
|
||||
|
||||
if (!targetWidth || !targetHeight) {
|
||||
throw new Error("无法读取参考图尺寸");
|
||||
}
|
||||
|
||||
const generatedMetadata = await sharp(generatedBuffer, { failOn: "none" })
|
||||
.rotate()
|
||||
.metadata();
|
||||
if (generatedMetadata.width === targetWidth && generatedMetadata.height === targetHeight) {
|
||||
return {
|
||||
originalUrl: params.generatedImageUrl,
|
||||
thumbnailUrl: params.generatedThumbnailUrl || params.generatedImageUrl,
|
||||
imageSize: `${targetWidth}x${targetHeight}`,
|
||||
};
|
||||
|
||||
if (!targetWidth || !targetHeight) {
|
||||
try {
|
||||
const referenceBuffer = await fetchImageBufferFromUrl(params.referenceImageUrl);
|
||||
const referenceMetadata = await sharp(referenceBuffer, { failOn: "none" })
|
||||
.rotate()
|
||||
.metadata();
|
||||
targetWidth = referenceMetadata.width;
|
||||
targetHeight = referenceMetadata.height;
|
||||
} catch (error) {
|
||||
chatApiLogger.warn("[Chat API] Failed to read replacement reference size, hosting generated output as-is:", {
|
||||
referenceImageUrl: params.referenceImageUrl,
|
||||
generatedImageUrl: params.generatedImageUrl,
|
||||
error: error instanceof Error ? error.message : "unknown",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const normalizedBuffer = await sharp(generatedBuffer, { failOn: "none" })
|
||||
.rotate()
|
||||
.resize(targetWidth, targetHeight, {
|
||||
// Keep the model output proportional when adapting it back to the reference page.
|
||||
// `fill` stretches the picture and can squash products; `cover` behaves like a screenshot crop.
|
||||
fit: "cover",
|
||||
position: "centre",
|
||||
withoutEnlargement: false,
|
||||
})
|
||||
.png()
|
||||
.toBuffer();
|
||||
const outputWidth = targetWidth || generatedMetadata.width;
|
||||
const outputHeight = targetHeight || generatedMetadata.height;
|
||||
|
||||
if (!outputWidth || !outputHeight) {
|
||||
throw new Error("无法读取结果图尺寸");
|
||||
}
|
||||
|
||||
const imagePipeline = sharp(generatedBuffer, { failOn: "none" }).rotate();
|
||||
const normalizedBuffer =
|
||||
targetWidth && targetHeight
|
||||
? await imagePipeline
|
||||
.resize(targetWidth, targetHeight, {
|
||||
// Keep the model output proportional when adapting it back to the reference page.
|
||||
// `fill` stretches the picture and can squash products; `cover` behaves like a screenshot crop.
|
||||
fit: "cover",
|
||||
position: "centre",
|
||||
withoutEnlargement: false,
|
||||
})
|
||||
.png()
|
||||
.toBuffer()
|
||||
: await imagePipeline.png().toBuffer();
|
||||
const thumbnailBuffer = await createAgentImageThumbnailBuffer(normalizedBuffer);
|
||||
|
||||
const uniqueSuffix = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
||||
@ -167,7 +173,7 @@ export async function normalizeReplacementResultImage(params: {
|
||||
return {
|
||||
originalUrl: originalUpload.url,
|
||||
thumbnailUrl: thumbnailUpload.url,
|
||||
imageSize: `${targetWidth}x${targetHeight}`,
|
||||
imageSize: `${outputWidth}x${outputHeight}`,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -249,6 +249,7 @@ import {
|
||||
ensureStructuredAgentFriendlyMessage,
|
||||
extractMessageImageAssetIds,
|
||||
extractMessageImageUrls,
|
||||
isRemoteImageAccessible,
|
||||
injectHistoryImagesToLastUserMessage,
|
||||
normalizeAssistantImageMarkdown,
|
||||
normalizeResolvedTargetImageUrls,
|
||||
@ -3544,6 +3545,12 @@ export async function POST(request: Request) {
|
||||
? normalizeError.message
|
||||
: "unknown",
|
||||
});
|
||||
const rawResultAccessible = await isRemoteImageAccessible(
|
||||
firstImage.originalUrl
|
||||
).catch(() => false);
|
||||
if (!rawResultAccessible) {
|
||||
throw normalizeError;
|
||||
}
|
||||
}
|
||||
|
||||
await emitReplacementResultMessage({
|
||||
@ -4341,6 +4348,12 @@ export async function POST(request: Request) {
|
||||
? normalizeError.message
|
||||
: "unknown",
|
||||
});
|
||||
const rawResultAccessible = await isRemoteImageAccessible(
|
||||
firstImage.originalUrl
|
||||
).catch(() => false);
|
||||
if (!rawResultAccessible) {
|
||||
throw normalizeError;
|
||||
}
|
||||
}
|
||||
chatApiLogger.info("[Chat API] Replacement image generation completed:", {
|
||||
mode: replacementSourceType,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user