fix(canvas): 局部重绘、图片规格与任务参数修复

This commit is contained in:
Rou
2026-09-09 14:22:21 +08:00
parent bacd502f5c
commit cd2ad4d700
13 changed files with 124 additions and 45 deletions

View File

@@ -47,7 +47,7 @@ export function CanvasProjectMediaDialogs({
<>
{cropNode?.metadata?.content ? <CanvasNodeCropDialog dataUrl={cropNode.metadata.content} open onClose={onCloseCrop} onConfirm={(crop) => onCrop(cropNode, crop)} /> : null}
{annotationNode?.metadata?.content ? <CanvasNodeAnnotationDialog image={{ url: annotationNode.metadata.content, storageKey: annotationNode.metadata.storageKey }} open onClose={onCloseAnnotation} onConfirm={(dataUrl) => onAnnotate(annotationNode, dataUrl)} /> : null}
{maskEditNode?.metadata?.content ? <CanvasNodeMaskEditDialog dataUrl={maskEditNode.metadata.content} config={config} open onClose={onCloseMaskEdit} onConfirm={(payload) => onMaskEdit(maskEditNode, payload)} /> : null}
{maskEditNode?.metadata?.content ? <CanvasNodeMaskEditDialog dataUrl={maskEditNode.metadata.content} config={{ ...config, model: maskEditNode.metadata.model || config.model, imageModel: maskEditNode.metadata.model || config.imageModel, size: maskEditNode.metadata.size || config.size, quality: maskEditNode.metadata.quality || config.quality, count: String(maskEditNode.metadata.count || config.count) }} open onClose={onCloseMaskEdit} onConfirm={(payload) => onMaskEdit(maskEditNode, payload)} /> : null}
{splitNode?.metadata?.content ? <CanvasNodeSplitDialog dataUrl={splitNode.metadata.content} open onClose={onCloseSplit} onConfirm={(params) => onSplit(splitNode, params)} /> : null}
{upscaleNode?.metadata?.content ? <CanvasNodeUpscaleDialog dataUrl={upscaleNode.metadata.content} open onClose={onCloseUpscale} onConfirm={(params) => onUpscale(upscaleNode, params)} /> : null}
</>

View File

@@ -36,12 +36,22 @@ import { mergeVideos, type MergeVideoProgress } from "@/lib/canvas/canvas-video-
import { extractVideoAudio, trimVideoSegment } from "@/lib/canvas/canvas-video-segment";
import { generationErrorMessage } from "@/lib/generation-error";
import { modelCapabilityConfigFor } from "@/lib/model-capabilities";
import { defaultImageParamsForModel } from "@/lib/model-selection";
import { navigateToSettings } from "@/lib/settings-navigation";
import { storeGeneratedVideo } from "@/services/api/video";
import { getMediaBlob, uploadMediaFile } from "@/services/file-storage";
import { uploadImage } from "@/services/image-storage";
import { ensureCanvasNodeAsset } from "@/services/project-asset-sync";
import type { GenerationTask } from "@/services/api/task-center";
function normalizeMaskEditQuality(quality: string | undefined, size: string | undefined) {
const value = String(quality || "").trim().toLowerCase();
if (value && value !== "auto" && value !== "any") return value;
const match = String(size || "").trim().toLowerCase().match(/^(\d+)x(\d+)$/);
if (!match) return quality || "auto";
const pixels = Number(match[1]) * Number(match[2]);
return pixels <= 2_000_000 ? "1k" : pixels <= 4_300_000 ? "2k" : pixels <= 8_294_400 ? "4k" : quality || "auto";
}
import { defaultConfig, resolveModelRequestConfig, useConfigStore, useEffectiveConfig, type AiConfig } from "@/stores/use-config-store";
import { CanvasNodeType, type CanvasConnection, type CanvasNodeData, type ContextMenuState } from "@/types/canvas";
import type { StartCanvasUploadStatus } from "./use-canvas-upload";
@@ -576,13 +586,22 @@ export function useCanvasMediaTools({
const maskEditImageNode = useCallback(async (node: CanvasNodeData, payload: CanvasImageMaskEditPayload) => {
if (!node.metadata?.content) return;
const baseGenerationConfig = buildGenerationConfig(effectiveConfig, node, "image");
const selectedModel = payload.generationConfig?.model || payload.generationConfig?.imageModel || baseGenerationConfig.model;
const modelDefaults = defaultImageParamsForModel(baseGenerationConfig, selectedModel);
const selectedImageProfile = modelCapabilityConfigFor(baseGenerationConfig, selectedModel).image;
if (!selectedImageProfile?.references.maskSupported) {
message.error("当前图片模型不支持局部重绘蒙版,请选择支持蒙版编辑的模型");
return;
}
const generationConfig = {
...baseGenerationConfig,
...payload.generationConfig,
model: payload.generationConfig?.model || payload.generationConfig?.imageModel || baseGenerationConfig.model,
model: selectedModel,
imageModel: payload.generationConfig?.imageModel || payload.generationConfig?.model || effectiveConfig.imageModel,
quality: normalizeMaskEditQuality(payload.generationConfig?.quality || node.metadata?.quality || baseGenerationConfig.quality || modelDefaults.quality, payload.generationConfig?.size || node.metadata?.size || baseGenerationConfig.size || modelDefaults.size),
count: String(payload.generationConfig?.count || 1),
size: payload.generationConfig?.size || node.metadata?.size || "auto",
// 原图像素尺寸不是模型的输出尺寸合同;非高级设置时使用模型默认尺寸,避免把节点尺寸误发给上游。
size: payload.generationConfig?.size || node.metadata?.size || modelDefaults.size,
};
if (!isAiConfigReady(generationConfig, generationConfig.model)) {
navigateToSettings({ continueCreation: true });