Support composite op with non-sRGB pipeline colourspace (#4412)

This commit is contained in:
Kleis Auke Wolthuizen 2025-06-12 11:32:24 +02:00 committed by GitHub
parent 91f1b58f31
commit 4d1f7e051d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 4 deletions

View File

@ -669,7 +669,6 @@ class PipelineWorker : public Napi::AsyncWorker {
sharp::ImageType compositeImageType = sharp::ImageType::UNKNOWN; sharp::ImageType compositeImageType = sharp::ImageType::UNKNOWN;
composite->input->access = access; composite->input->access = access;
std::tie(compositeImage, compositeImageType) = sharp::OpenInput(composite->input); std::tie(compositeImage, compositeImageType) = sharp::OpenInput(composite->input);
compositeImage = sharp::EnsureColourspace(compositeImage, baton->colourspacePipeline);
if (composite->input->autoOrient) { if (composite->input->autoOrient) {
// Respect EXIF Orientation // Respect EXIF Orientation
@ -734,8 +733,7 @@ class PipelineWorker : public Napi::AsyncWorker {
// gravity was used for extract_area, set it back to its default value of 0 // gravity was used for extract_area, set it back to its default value of 0
composite->gravity = 0; composite->gravity = 0;
} }
// Ensure image to composite is sRGB with unpremultiplied alpha // Ensure image to composite is with unpremultiplied alpha
compositeImage = compositeImage.colourspace(VIPS_INTERPRETATION_sRGB);
compositeImage = sharp::EnsureAlpha(compositeImage, 1); compositeImage = sharp::EnsureAlpha(compositeImage, 1);
if (composite->premultiplied) compositeImage = compositeImage.unpremultiply(); if (composite->premultiplied) compositeImage = compositeImage.unpremultiply();
// Calculate position // Calculate position
@ -760,7 +758,12 @@ class PipelineWorker : public Napi::AsyncWorker {
xs.push_back(left); xs.push_back(left);
ys.push_back(top); ys.push_back(top);
} }
image = VImage::composite(images, modes, VImage::option()->set("x", xs)->set("y", ys)); image = VImage::composite(images, modes, VImage::option()
->set("compositing_space", baton->colourspacePipeline == VIPS_INTERPRETATION_LAST
? VIPS_INTERPRETATION_sRGB
: baton->colourspacePipeline)
->set("x", xs)
->set("y", ys));
image = sharp::RemoveGifPalette(image); image = sharp::RemoveGifPalette(image);
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -122,6 +122,26 @@ describe('composite', () => {
}); });
}); });
it('scrgb pipeline', () => {
const filename = 'composite-red-scrgb.png';
const actual = fixtures.path(`output.${filename}`);
const expected = fixtures.expected(filename);
return sharp({
create: {
width: 32, height: 32, channels: 4, background: red
}
})
.pipelineColourspace('scrgb')
.composite([{
input: fixtures.inputPngWithTransparency16bit,
blend: 'color-burn'
}])
.toFile(actual)
.then(() => {
fixtures.assertMaxColourDistance(actual, expected);
});
});
it('multiple', async () => { it('multiple', async () => {
const filename = 'composite-multiple.png'; const filename = 'composite-multiple.png';
const actual = fixtures.path(`output.${filename}`); const actual = fixtures.path(`output.${filename}`);