From f17ac0659159575e5308708b11c7d9fdfbec495b Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 2 Jul 2025 17:47:45 +0000 Subject: [PATCH] Fix PSD export to use layer content bounds and crop canvas Co-authored-by: kent --- .../hooks/useExportCanvasToPSD.ts | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/invokeai/frontend/web/src/features/controlLayers/hooks/useExportCanvasToPSD.ts b/invokeai/frontend/web/src/features/controlLayers/hooks/useExportCanvasToPSD.ts index a96e678721..a334346050 100644 --- a/invokeai/frontend/web/src/features/controlLayers/hooks/useExportCanvasToPSD.ts +++ b/invokeai/frontend/web/src/features/controlLayers/hooks/useExportCanvasToPSD.ts @@ -71,15 +71,29 @@ export const useExportCanvasToPSD = () => { const psdLayers: Layer[] = await Promise.all( adapters.map((adapter, index) => { const layer = adapter.state; - const canvas = adapter.getCanvas(); + + // Get the actual content bounds for this layer (excluding transparent regions) const layerPosition = adapter.state.position; + const pixelRect = adapter.transformer.$pixelRect.get(); + + // Calculate the layer's content bounds in stage coordinates + const layerContentBounds = { + x: layerPosition.x + pixelRect.x, + y: layerPosition.y + pixelRect.y, + width: pixelRect.width, + height: pixelRect.height, + }; + + // Get the canvas cropped to the layer's actual content bounds + const canvas = adapter.getCanvas({ rect: layerContentBounds }); const layerDataPSD: Layer = { name: layer.name || `Layer ${index + 1}`, - left: Math.floor(layerPosition.x - visibleRect.x), - top: Math.floor(layerPosition.y - visibleRect.y), - right: Math.floor(layerPosition.x - visibleRect.x + canvas.width), - bottom: Math.floor(layerPosition.y - visibleRect.y + canvas.height), + // Position relative to the visible rect, using the actual content bounds + left: Math.floor(layerContentBounds.x - visibleRect.x), + top: Math.floor(layerContentBounds.y - visibleRect.y), + right: Math.floor(layerContentBounds.x - visibleRect.x + canvas.width), + bottom: Math.floor(layerContentBounds.y - visibleRect.y + canvas.height), opacity: Math.floor(layer.opacity * 255), hidden: false, blendMode: 'normal',