mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
Ensure image is unpremultiplied before composite #3334
This commit is contained in:
parent
a44168c8c7
commit
a618ce7a15
@ -52,6 +52,9 @@ Requires libvips v8.13.0
|
||||
Emit warnings when previous calls in the same pipeline will be ignored.
|
||||
[#3319](https://github.com/lovell/sharp/issues/3319)
|
||||
|
||||
* Ensure resized image is unpremultiplied before composite.
|
||||
[#3334](https://github.com/lovell/sharp/issues/3334)
|
||||
|
||||
## v0.30 - *dresser*
|
||||
|
||||
Requires libvips v8.12.2
|
||||
|
@ -590,6 +590,18 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
baton->sharpenX1, baton->sharpenY2, baton->sharpenY3);
|
||||
}
|
||||
|
||||
// Reverse premultiplication after all transformations
|
||||
if (shouldPremultiplyAlpha) {
|
||||
image = image.unpremultiply();
|
||||
// Cast pixel values to integer
|
||||
if (sharp::Is16Bit(image.interpretation())) {
|
||||
image = image.cast(VIPS_FORMAT_USHORT);
|
||||
} else {
|
||||
image = image.cast(VIPS_FORMAT_UCHAR);
|
||||
}
|
||||
}
|
||||
baton->premultiplied = shouldPremultiplyAlpha;
|
||||
|
||||
// Composite
|
||||
if (shouldComposite) {
|
||||
std::vector<VImage> images = { image };
|
||||
@ -670,18 +682,6 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
image = VImage::composite(images, modes, VImage::option()->set("x", xs)->set("y", ys));
|
||||
}
|
||||
|
||||
// Reverse premultiplication after all transformations:
|
||||
if (shouldPremultiplyAlpha) {
|
||||
image = image.unpremultiply();
|
||||
// Cast pixel values to integer
|
||||
if (sharp::Is16Bit(image.interpretation())) {
|
||||
image = image.cast(VIPS_FORMAT_USHORT);
|
||||
} else {
|
||||
image = image.cast(VIPS_FORMAT_UCHAR);
|
||||
}
|
||||
}
|
||||
baton->premultiplied = shouldPremultiplyAlpha;
|
||||
|
||||
// Gamma decoding (brighten)
|
||||
if (baton->gammaOut >= 1 && baton->gammaOut <= 3) {
|
||||
image = sharp::Gamma(image, baton->gammaOut);
|
||||
|
@ -447,4 +447,26 @@ describe('composite', () => {
|
||||
assert.strictEqual(info.width, 40);
|
||||
assert.strictEqual(info.height, 40);
|
||||
});
|
||||
|
||||
it('Ensure implict unpremultiply after resize but before composite', async () => {
|
||||
const [r, g, b, a] = await sharp({
|
||||
create: {
|
||||
width: 1, height: 1, channels: 4, background: 'saddlebrown'
|
||||
}
|
||||
})
|
||||
.resize({ width: 8 })
|
||||
.composite([{
|
||||
input: Buffer.from([255, 255, 255, 128]),
|
||||
raw: { width: 1, height: 1, channels: 4 },
|
||||
tile: true,
|
||||
blend: 'dest-in'
|
||||
}])
|
||||
.raw()
|
||||
.toBuffer();
|
||||
|
||||
assert.strictEqual(r, 139);
|
||||
assert.strictEqual(g, 69);
|
||||
assert.strictEqual(b, 19);
|
||||
assert.strictEqual(a, 128);
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user