diff --git a/lib/agents/psd-template-renderer.ts b/lib/agents/psd-template-renderer.ts index 12be3d623..750a53140 100644 --- a/lib/agents/psd-template-renderer.ts +++ b/lib/agents/psd-template-renderer.ts @@ -9,6 +9,7 @@ import { isAgentPsdTextLayerSlot, resolveAgentPsdTextLayerEffectiveAlign, type AgentPsdTemplate, + type AgentPsdTemplateImageLayerSlot, } from "@/lib/agents/psd-template-config"; import type { AgentPsdFont } from "@/lib/agents/psd-font-config"; import { ensurePsdFontAvailableForRender } from "@/lib/agents/psd-font-runtime"; @@ -175,6 +176,22 @@ function getStoredLayerSourceUrl(layer: AgentPsdTemplate["layers"][number]) { ); } +function getDefaultSourceImageLayer( + layers: AgentPsdTemplate["layers"] +) { + const editableImageLayers = layers.filter( + (layer): layer is AgentPsdTemplateImageLayerSlot => + isAgentPsdTemplateLayerUserEditable(layer) && + isAgentPsdImageLayerSlot(layer) + ); + + return ( + editableImageLayers.find((layer) => layer.isDefaultResultSource) || + editableImageLayers[0] || + null + ); +} + function resolveTextOverlayFrame(params: { layerWidth: number; layerHeight: number; @@ -445,19 +462,16 @@ export async function renderAgentPsdTemplate(params: { const hasDedicatedRenderBase = Boolean(renderBaseUrl) && renderBaseUrl !== String(template.previewUrl || "").trim(); + const defaultSourceImageLayerId = + getDefaultSourceImageLayer(orderedTemplateLayers)?.id || ""; const hasHiddenStaticLayer = orderedTemplateLayers.some( (layer) => !isAgentPsdTemplateLayerUserEditable(layer) && hiddenLayerIdSet.has(layer.id) ); - const hasMissingVisibleStoredLayerSource = orderedTemplateLayers.some( - (layer) => - !hiddenLayerIdSet.has(layer.id) && !getStoredLayerSourceUrl(layer) - ); const shouldUseRenderBaseFallback = hasDedicatedRenderBase && - !hasHiddenStaticLayer && - hasMissingVisibleStoredLayerSource; + !hasHiddenStaticLayer; function getLayerPositionOffset(layerId: string) { return normalizeTextPositionOffset(layerPositionOffsets[layerId]); @@ -510,6 +524,9 @@ export async function renderAgentPsdTemplate(params: { const storedLayerSourceUrl = getStoredLayerSourceUrl(layer); if (!isAgentPsdTemplateLayerUserEditable(layer)) { + if (shouldUseRenderBaseFallback) { + continue; + } pushAsset( storedLayerSourceUrl, "PSD 图层素材", @@ -660,7 +677,12 @@ export async function renderAgentPsdTemplate(params: { await prefetchRenderAssets(); - if (shouldUseRenderBaseFallback) { + let didAppendRenderBase = false; + async function appendRenderBaseOverlay() { + if (!shouldUseRenderBaseFallback || didAppendRenderBase) { + return; + } + didAppendRenderBase = true; const renderBaseBuffer = await readCachedBuffer(renderBaseUrl, "PSD 模板底图"); await appendBufferOverlay({ input: renderBaseBuffer, @@ -671,22 +693,36 @@ export async function renderAgentPsdTemplate(params: { }); } + if ( + shouldUseRenderBaseFallback && + (!defaultSourceImageLayerId || hiddenLayerIdSet.has(defaultSourceImageLayerId)) + ) { + await appendRenderBaseOverlay(); + } + for (const layer of [...orderedTemplateLayers].reverse()) { if (hiddenLayerIdSet.has(layer.id)) { continue; } if (!isAgentPsdTemplateLayerUserEditable(layer)) { + if (shouldUseRenderBaseFallback) { + continue; + } await appendStoredLayer(layer, { optional: shouldUseRenderBaseFallback }); continue; } if (isAgentPsdImageLayerSlot(layer)) { + const isDefaultSourceImageLayer = layer.id === defaultSourceImageLayerId; const assignmentUrl = String(imageAssignments[layer.id] || "").trim(); if (!assignmentUrl) { await appendStoredLayer(layer, { optional: shouldUseRenderBaseFallback, }); + if (isDefaultSourceImageLayer) { + await appendRenderBaseOverlay(); + } continue; } @@ -756,6 +792,9 @@ export async function renderAgentPsdTemplate(params: { width: slotOverlay.width, height: slotOverlay.height, }); + if (isDefaultSourceImageLayer) { + await appendRenderBaseOverlay(); + } if (!didAppend) continue; continue; } @@ -823,6 +862,9 @@ export async function renderAgentPsdTemplate(params: { width: layer.width, height: layer.height, }); + if (isDefaultSourceImageLayer) { + await appendRenderBaseOverlay(); + } if (!didAppend) continue; continue; }