mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 18:40:16 +02:00
Improve extractChannel support for 16-bit output #3453
This commit is contained in:
parent
789d4851ea
commit
01ffa80338
@ -12,6 +12,9 @@ Requires libvips v8.13.3
|
|||||||
* Prevent possible race condition awaiting metadata of Stream-based input.
|
* Prevent possible race condition awaiting metadata of Stream-based input.
|
||||||
[#3451](https://github.com/lovell/sharp/issues/3451)
|
[#3451](https://github.com/lovell/sharp/issues/3451)
|
||||||
|
|
||||||
|
* Improve `extractChannel` support for 16-bit output colourspaces.
|
||||||
|
[#3453](https://github.com/lovell/sharp/issues/3453)
|
||||||
|
|
||||||
### v0.31.2 - 4th November 2022
|
### v0.31.2 - 4th November 2022
|
||||||
|
|
||||||
* Upgrade to libvips v8.13.3 for upstream bug fixes.
|
* Upgrade to libvips v8.13.3 for upstream bug fixes.
|
||||||
|
@ -98,7 +98,7 @@ function extractChannel (channel) {
|
|||||||
} else {
|
} else {
|
||||||
throw is.invalidParameterError('channel', 'integer or one of: red, green, blue, alpha', channel);
|
throw is.invalidParameterError('channel', 'integer or one of: red, green, blue, alpha', channel);
|
||||||
}
|
}
|
||||||
return this.toColourspace('b-w');
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -701,24 +701,6 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
image = sharp::Tint(image, baton->tintA, baton->tintB);
|
image = sharp::Tint(image, baton->tintA, baton->tintB);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract an image channel (aka vips band)
|
|
||||||
if (baton->extractChannel > -1) {
|
|
||||||
if (baton->extractChannel >= image.bands()) {
|
|
||||||
if (baton->extractChannel == 3 && sharp::HasAlpha(image)) {
|
|
||||||
baton->extractChannel = image.bands() - 1;
|
|
||||||
} else {
|
|
||||||
(baton->err).append("Cannot extract channel from image. Too few channels in image.");
|
|
||||||
return Error();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
VipsInterpretation const interpretation = sharp::Is16Bit(image.interpretation())
|
|
||||||
? VIPS_INTERPRETATION_GREY16
|
|
||||||
: VIPS_INTERPRETATION_B_W;
|
|
||||||
image = image
|
|
||||||
.extract_band(baton->extractChannel)
|
|
||||||
.copy(VImage::option()->set("interpretation", interpretation));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove alpha channel, if any
|
// Remove alpha channel, if any
|
||||||
if (baton->removeAlpha) {
|
if (baton->removeAlpha) {
|
||||||
image = sharp::RemoveAlpha(image);
|
image = sharp::RemoveAlpha(image);
|
||||||
@ -744,6 +726,26 @@ class PipelineWorker : public Napi::AsyncWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extract channel
|
||||||
|
if (baton->extractChannel > -1) {
|
||||||
|
if (baton->extractChannel >= image.bands()) {
|
||||||
|
if (baton->extractChannel == 3 && sharp::HasAlpha(image)) {
|
||||||
|
baton->extractChannel = image.bands() - 1;
|
||||||
|
} else {
|
||||||
|
(baton->err)
|
||||||
|
.append("Cannot extract channel ").append(std::to_string(baton->extractChannel))
|
||||||
|
.append(" from image with channels 0-").append(std::to_string(image.bands() - 1));
|
||||||
|
return Error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VipsInterpretation colourspace = sharp::Is16Bit(image.interpretation())
|
||||||
|
? VIPS_INTERPRETATION_GREY16
|
||||||
|
: VIPS_INTERPRETATION_B_W;
|
||||||
|
image = image
|
||||||
|
.extract_band(baton->extractChannel)
|
||||||
|
.copy(VImage::option()->set("interpretation", colourspace));
|
||||||
|
}
|
||||||
|
|
||||||
// Apply output ICC profile
|
// Apply output ICC profile
|
||||||
if (!baton->withMetadataIcc.empty()) {
|
if (!baton->withMetadataIcc.empty()) {
|
||||||
image = image.icc_transform(
|
image = image.icc_transform(
|
||||||
|
BIN
test/fixtures/expected/extract-lch.jpg
vendored
BIN
test/fixtures/expected/extract-lch.jpg
vendored
Binary file not shown.
Before Width: | Height: | Size: 13 KiB |
@ -54,19 +54,13 @@ describe('Image channel extraction', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('With colorspace conversion', function (done) {
|
it('With colorspace conversion', async () => {
|
||||||
const output = fixtures.path('output.extract-lch.jpg');
|
const [chroma] = await sharp({ create: { width: 1, height: 1, channels: 3, background: 'red' } })
|
||||||
sharp(fixtures.inputJpg)
|
|
||||||
.extractChannel(1)
|
|
||||||
.toColourspace('lch')
|
.toColourspace('lch')
|
||||||
.resize(320, 240, { fastShrinkOnLoad: false })
|
.extractChannel(1)
|
||||||
.toFile(output, function (err, info) {
|
.toBuffer();
|
||||||
if (err) throw err;
|
|
||||||
assert.strictEqual(320, info.width);
|
assert.strictEqual(chroma, 104);
|
||||||
assert.strictEqual(240, info.height);
|
|
||||||
fixtures.assertMaxColourDistance(output, fixtures.expected('extract-lch.jpg'), 9);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Alpha from 16-bit PNG', function (done) {
|
it('Alpha from 16-bit PNG', function (done) {
|
||||||
@ -108,12 +102,12 @@ describe('Image channel extraction', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Non-existent channel', function (done) {
|
it('Non-existent channel', async () =>
|
||||||
sharp(fixtures.inputPng)
|
await assert.rejects(
|
||||||
.extractChannel(1)
|
() => sharp({ create: { width: 1, height: 1, channels: 3, background: 'red' } })
|
||||||
.toBuffer(function (err) {
|
.extractChannel(3)
|
||||||
assert(err instanceof Error);
|
.toBuffer(),
|
||||||
done();
|
/Cannot extract channel 3 from image with channels 0-2/
|
||||||
});
|
)
|
||||||
});
|
);
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user