修复图片改造尺寸保持

保持图片改造提交与画布回填的原图尺寸
在 VectorEngine 边界对齐非 16 倍数参考图并恢复目标尺寸
补充前后端回归测试与编辑器尺寸契约文档
This commit is contained in:
2026-07-11 18:10:00 +08:00
parent d756e8e04b
commit 300e69c97d
9 changed files with 243 additions and 54 deletions
@@ -287,8 +287,8 @@ describe('ImageCanvasGenerationLayerModel', () => {
const sourceLayer = createSourceLayer({
width: 320,
height: 240,
originalWidth: 1024,
originalHeight: 768,
originalWidth: 1537,
originalHeight: 1025,
});
const layer = applyImageEditResultToSourceLayer({
generated: createGenerated({
@@ -313,10 +313,10 @@ describe('ImageCanvasGenerationLayerModel', () => {
id: 'layer-source',
title: '源图',
src: 'data:image/png;base64,edited',
width: 1536,
height: 1024,
originalWidth: 1536,
originalHeight: 1024,
width: 320,
height: 240,
originalWidth: 1537,
originalHeight: 1025,
resourceId: 'resource-edited',
sourceResourceId: 'resource-source',
objectKey: 'generated/edited.png',
@@ -247,18 +247,10 @@ export function applyImageEditResultToSourceLayer({
sourceLayer: CanvasLayer;
generationInputs: CanvasGenerationInputs;
}): CanvasLayer {
const originalWidth =
generated.width || sourceLayer.originalWidth || sourceLayer.width;
const originalHeight =
generated.height || sourceLayer.originalHeight || sourceLayer.height;
const { width, height } = resolveLayerResolutionSize(
originalWidth,
originalHeight,
{
width: sourceLayer.width,
height: sourceLayer.height,
},
);
const originalWidth = sourceLayer.originalWidth || sourceLayer.width;
const originalHeight = sourceLayer.originalHeight || sourceLayer.height;
const width = sourceLayer.width;
const height = sourceLayer.height;
return applyGeneratedMetadata(
{
...sourceLayer,
@@ -122,6 +122,8 @@ describe('ImageCanvasGenerationSubmissionModel', () => {
const sourceLayer = createLayer({
objectKey: 'generated-character-drafts/editor/source.png',
assetKind: 'character',
originalWidth: 1537,
originalHeight: 1025,
});
const plan = buildImageGenerationSubmissionPlan({
@@ -150,7 +152,7 @@ describe('ImageCanvasGenerationSubmissionModel', () => {
normalizedPrompt: '把当前图改成雨天',
sourceLayer,
editInput: {
size: '1024x768',
size: '1537x1025',
model: IMAGE_MODEL_GPT_IMAGE_2,
},
result: {
@@ -41,11 +41,8 @@ import {
DEFAULT_VIDEO_WEB_SEARCH_ENABLED,
ICON_DESCRIPTION_LIMIT,
IMAGE_MODEL_GPT_IMAGE_2,
inferEditorImageAspectRatio,
inferEditorImageSizeLabel,
normalizeEditorImageModel,
resolveCharacterAnimationSourceImageSrc,
resolveEditorImageGenerationPixelSize,
SEEDANCE_VIDEO_REFERENCE_LIMITS,
SPEC_GENERATION_ASPECT_RATIO,
SPEC_GENERATION_IMAGE_SIZE,
@@ -260,29 +257,12 @@ export function buildImageGenerationSubmissionPlan({
const basePrompt = dialog.prompt.trim() || '快速编辑图片';
const normalizedQuickEditPrompt = basePrompt;
const imageModel = IMAGE_MODEL_GPT_IMAGE_2;
const aspectRatio =
dialog.aspectRatio ??
inferEditorImageAspectRatio(
sourceLayer.originalWidth,
sourceLayer.originalHeight,
);
const imageSize =
dialog.imageSize ??
inferEditorImageSizeLabel(
sourceLayer.originalWidth,
sourceLayer.originalHeight,
);
const outputSize = resolveEditorImageGenerationPixelSize({
model: imageModel,
aspectRatio,
imageSize,
});
return {
kind: 'quick-edit',
normalizedPrompt: normalizedQuickEditPrompt,
sourceLayer,
editInput: {
size: `${outputSize.width}x${outputSize.height}`,
size: `${sourceLayer.originalWidth}x${sourceLayer.originalHeight}`,
model: imageModel,
},
result: {
@@ -535,7 +535,13 @@ describe('useImageCanvasGenerationSubmissionWorkflow', () => {
editEditorImageMock.mockResolvedValueOnce(
createGenerated({ prompt: '快速修图' }),
);
render(<SubmissionWorkflowHarness />);
render(
<SubmissionWorkflowHarness
initialLayers={[
createLayer({ originalWidth: 1537, originalHeight: 1025 }),
]}
/>,
);
fireEvent.click(screen.getByRole('button', { name: '打开快速编辑' }));
fireEvent.click(screen.getByRole('button', { name: '填写快速编辑' }));
@@ -550,7 +556,7 @@ describe('useImageCanvasGenerationSubmissionWorkflow', () => {
expect.objectContaining({
prompt: '快速修图',
sourceImageSrc: 'resource-source',
size: '1024x768',
size: '1537x1025',
model: 'gpt-image-2',
}),
);
@@ -1268,12 +1268,11 @@ export function useImageCanvasGenerationSubmissionWorkflow({
quickEditSourceLayer.originalWidth,
quickEditSourceLayer.originalHeight,
);
const quickEditOutputSize = resolveEditorImageGenerationPixelSize({
model: quickEditPanel.model,
aspectRatio: quickEditAspectRatio,
imageSize: quickEditImageSize,
});
const quickEditSize = `${quickEditOutputSize.width}x${quickEditOutputSize.height}`;
const quickEditOutputSize = {
width: quickEditSourceLayer.originalWidth,
height: quickEditSourceLayer.originalHeight,
};
const quickEditSize = `${quickEditSourceLayer.originalWidth}x${quickEditSourceLayer.originalHeight}`;
const basePrompt =
quickEditPanel.prompt.trim() ||
(panelMode === 'redraw' ? '重绘图片' : '快速编辑图片');
@@ -1678,6 +1677,7 @@ export function useImageCanvasGenerationSubmissionWorkflow({
editEditorImage({
prompt: submissionPlan.normalizedPrompt,
sourceImageSrc: referenceImageSrc,
size: `${submissionPlan.sourceLayer.originalWidth}x${submissionPlan.sourceLayer.originalHeight}`,
projectId,
assetKind: submissionPlan.sourceLayer.assetKind,
generationInputs: submissionPlan.generationInputs,