mirror of
https://github.com/Comfy-Org/ComfyUI.git
synced 2026-08-18 23:38:29 +08:00
ImageBlend ran the blend maths over every channel, so for RGBA inputs the alpha was blended as if it were colour. In difference mode two fully opaque images produced 1.0 - 1.0 = 0.0 and the result came back completely transparent. Keep image1's alpha, which is the base being blended. CORE-392
85 lines
2.5 KiB
Python
85 lines
2.5 KiB
Python
import pytest
|
|
import torch
|
|
|
|
from comfy.cli_args import args as cli_args
|
|
|
|
if not torch.cuda.is_available():
|
|
cli_args.cpu = True
|
|
|
|
from comfy_extras.nodes_post_processing import Blend # noqa: E402
|
|
|
|
MODES = ["normal", "multiply", "screen", "overlay", "soft_light", "difference"]
|
|
|
|
|
|
def image(value, alpha=None, size=4):
|
|
channels = 3 if alpha is None else 4
|
|
t = torch.full((1, size, size, channels), value)
|
|
if alpha is not None:
|
|
t[..., 3] = alpha
|
|
return t
|
|
|
|
|
|
@pytest.mark.parametrize("mode", MODES)
|
|
def test_rgb_blend_is_unchanged(mode):
|
|
"""3 channel images must keep going through the untouched code path."""
|
|
image1, image2 = image(0.8), image(0.3)
|
|
|
|
out = Blend.execute(image1, image2, 0.5, mode).result[0]
|
|
|
|
assert out.shape == image1.shape
|
|
assert torch.all(out >= 0.0) and torch.all(out <= 1.0)
|
|
|
|
|
|
@pytest.mark.parametrize("mode", MODES)
|
|
def test_rgba_keeps_image1_alpha(mode):
|
|
image1, image2 = image(0.8, alpha=0.6), image(0.3, alpha=0.1)
|
|
|
|
out = Blend.execute(image1, image2, 0.5, mode).result[0]
|
|
|
|
assert out.shape[-1] == 4
|
|
assert torch.equal(out[..., 3], image1[..., 3])
|
|
|
|
|
|
@pytest.mark.parametrize("mode", MODES)
|
|
def test_two_opaque_images_stay_opaque(mode):
|
|
"""Regression: difference mode used to compute 1.0 - 1.0 and erase the image."""
|
|
image1, image2 = image(0.8, alpha=1.0), image(0.3, alpha=1.0)
|
|
|
|
out = Blend.execute(image1, image2, 1.0, mode).result[0]
|
|
|
|
assert torch.all(out[..., 3] == 1.0)
|
|
|
|
|
|
@pytest.mark.parametrize("mode", MODES)
|
|
def test_rgb_channels_still_blend_on_rgba(mode):
|
|
"""Preserving alpha must not stop the colour channels from blending.
|
|
|
|
Mid-tones on purpose: pure white over pure black is a fixed point for
|
|
several of the modes, so it would not prove anything.
|
|
"""
|
|
image1, image2 = image(0.6, alpha=1.0), image(0.25, alpha=1.0)
|
|
|
|
out = Blend.execute(image1, image2, 1.0, mode).result[0]
|
|
|
|
assert not torch.equal(out[..., :3], image1[..., :3])
|
|
|
|
|
|
def test_does_not_mutate_inputs():
|
|
image1, image2 = image(0.8, alpha=0.6), image(0.3, alpha=0.1)
|
|
before1, before2 = image1.clone(), image2.clone()
|
|
|
|
Blend.execute(image1, image2, 0.5, "difference")
|
|
|
|
assert torch.equal(image1, before1)
|
|
assert torch.equal(image2, before2)
|
|
|
|
|
|
def test_mismatched_channel_counts_still_supported():
|
|
"""image_alpha_fix (CORE-103) pads the RGB input; that must keep working."""
|
|
rgba, rgb = image(0.8, alpha=0.5), image(0.3)
|
|
|
|
out = Blend.execute(rgba, rgb, 0.5, "normal").result[0]
|
|
|
|
assert out.shape[-1] == 4
|
|
assert torch.equal(out[..., 3], rgba[..., 3])
|