diff --git a/src/components/__tests__/GenerateImageNode.test.tsx b/src/components/__tests__/GenerateImageNode.test.tsx
index b838dd6b..63aaf79d 100644
--- a/src/components/__tests__/GenerateImageNode.test.tsx
+++ b/src/components/__tests__/GenerateImageNode.test.tsx
@@ -379,6 +379,28 @@ describe("GenerateImageNode", () => {
expect(mockDownloadMedia).toHaveBeenCalledWith("https://cdn.example.com/full.png", "image");
});
+ it("should use the full output image while cropping and return to preview afterward", () => {
+ render(
+
+
+
+ );
+
+ const img = screen.getByAltText("Generated");
+ expect(img).toHaveAttribute("src", "https://cdn.example.com/full_thumb.webp");
+
+ fireEvent.click(screen.getByRole("button", { name: /Crop|裁剪/ }));
+
+ expect(img).toHaveAttribute("src", "https://cdn.example.com/full.png");
+
+ fireEvent.click(screen.getByRole("button", { name: "关闭编辑工具" }));
+
+ expect(img).toHaveAttribute("src", "https://cdn.example.com/full_thumb.webp");
+ });
+
it("should not resize the canvas node while rendering an output image", () => {
render(
diff --git a/src/components/__tests__/ImageInputNode.test.tsx b/src/components/__tests__/ImageInputNode.test.tsx
index 01cf0f71..adcbfd3a 100644
--- a/src/components/__tests__/ImageInputNode.test.tsx
+++ b/src/components/__tests__/ImageInputNode.test.tsx
@@ -308,6 +308,34 @@ describe("ImageInputNode", () => {
expect(img).toHaveClass("object-cover");
});
+ it("should use the full image while cropping and return to preview afterward", () => {
+ mockNodes = [{ id: propsWithImage.id, selected: true }];
+ render(
+
+
+
+ );
+
+ const img = screen.getByAltText("test-image.png");
+ expect(img).toHaveAttribute("src", "https://example.com/full_thumb.webp");
+
+ fireEvent.click(screen.getByRole("button", { name: "Crop" }));
+
+ expect(img).toHaveAttribute("src", "https://example.com/full.png");
+
+ fireEvent.click(screen.getByRole("button", { name: "关闭编辑工具" }));
+
+ expect(img).toHaveAttribute("src", "https://example.com/full_thumb.webp");
+ });
+
it("should show a load failure state when the image cannot be rendered", () => {
render(
diff --git a/src/components/nodes/GenerateImageNode.tsx b/src/components/nodes/GenerateImageNode.tsx
index 49ca3242..78ef2165 100644
--- a/src/components/nodes/GenerateImageNode.tsx
+++ b/src/components/nodes/GenerateImageNode.tsx
@@ -375,7 +375,7 @@ export function GenerateImageNodeView({ id, data, selected }: GenerateImageNodeV
}, [nodeData.status, displayError, t]);
const selectedNodeCount = useSelectedNodeCount();
- const editableImage = displayImage;
+ const editableImage = nodeData.outputImage || displayImage;
const downloadImage = nodeData.outputImage || editableImage;
const overlayImageDimensions = cropImageDimensions || asImageDimensions(nodeData.dimensions);
const showSelectedActions = Boolean(selected && selectedNodeCount === 1 && editableImage);
@@ -576,7 +576,7 @@ export function GenerateImageNodeView({ id, data, selected }: GenerateImageNodeV
onLoad={(event) => {
setImageRetryNonce(0);
const image = event.currentTarget;
- if (image.naturalWidth > 0 && image.naturalHeight > 0) {
+ if (renderedImageSrc === nodeData.outputImage && image.naturalWidth > 0 && image.naturalHeight > 0) {
const dimensions = { width: image.naturalWidth, height: image.naturalHeight };
setCropImageDimensions(dimensions);
updateMediaNodeData(id, { dimensions }, dimensions);
diff --git a/src/components/nodes/ImageInputNode.tsx b/src/components/nodes/ImageInputNode.tsx
index 27560b72..a02b24cd 100644
--- a/src/components/nodes/ImageInputNode.tsx
+++ b/src/components/nodes/ImageInputNode.tsx
@@ -124,7 +124,7 @@ export function ImageInputNodeView({ id, data, selected, renderInputHandle = fal
const [imageLoadFailed, setImageLoadFailed] = useState(false);
const isUploading = nodeData.uploadStatus === "loading";
const displayImage = displayFallbackImage || preferredDisplayImage;
- const imageSrc = displayImage;
+ const imageSrc = isCropping ? nodeData.image || displayImage : displayImage;
useEffect(() => {
setDisplayFallbackImage(null);
@@ -576,7 +576,7 @@ export function ImageInputNodeView({ id, data, selected, renderInputHandle = fal
onLoad={(event) => {
setImageLoadFailed(false);
const image = event.currentTarget;
- if (image.naturalWidth > 0 && image.naturalHeight > 0) {
+ if (imageSrc === nodeData.image && image.naturalWidth > 0 && image.naturalHeight > 0) {
const dimensions = { width: image.naturalWidth, height: image.naturalHeight };
if (nodeData.dimensions?.width !== dimensions.width || nodeData.dimensions?.height !== dimensions.height) {
updateMediaNodeData(id, { dimensions }, dimensions);