mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
Allow non-RGB input to embed/extend onto bg with alpha #646
This commit is contained in:
parent
61721bb086
commit
d2455267a8
@ -3,7 +3,7 @@
|
||||
# background
|
||||
|
||||
Set the background for the `embed`, `flatten` and `extend` operations.
|
||||
The default background is `{r: 0, g: 0, b: 0, a: 1}`, black without transparency.
|
||||
The default background is `{r: 0, g: 0, b: 0, alpha: 1}`, black without transparency.
|
||||
|
||||
Delegates to the _color_ module, which can throw an Error
|
||||
but is liberal in what it accepts, clipping values to sensible min/max.
|
||||
|
@ -37,6 +37,10 @@ Requires libvips v8.4.2.
|
||||
[#623](https://github.com/lovell/sharp/pull/623)
|
||||
[@ppaskaris](https://github.com/ppaskaris)
|
||||
|
||||
* Allow non-RGB input to embed/extend onto background with an alpha channel.
|
||||
[#646](https://github.com/lovell/sharp/issues/646)
|
||||
[@DaGaMs](https://github.com/DaGaMs)
|
||||
|
||||
### v0.16 - "*pencil*"
|
||||
|
||||
Requires libvips v8.3.3
|
||||
|
@ -29,7 +29,12 @@ const colourspace = {
|
||||
*/
|
||||
const background = function background (rgba) {
|
||||
const colour = color(rgba);
|
||||
this.options.background = colour.rgb().array().concat(colour.alpha() * 255);
|
||||
this.options.background = [
|
||||
colour.red(),
|
||||
colour.green(),
|
||||
colour.blue(),
|
||||
Math.round(colour.alpha() * 255)
|
||||
];
|
||||
return this;
|
||||
};
|
||||
|
||||
|
@ -61,7 +61,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"caw": "^2.0.0",
|
||||
"color": "^1.0.1",
|
||||
"color": "^1.0.2",
|
||||
"got": "^6.6.3",
|
||||
"nan": "^2.4.0",
|
||||
"semver": "^5.3.0",
|
||||
@ -71,7 +71,7 @@
|
||||
"async": "^2.1.4",
|
||||
"bufferutil": "^1.3.0",
|
||||
"cross-env": "^3.1.3",
|
||||
"documentation": "^4.0.0-beta15",
|
||||
"documentation": "^4.0.0-beta16",
|
||||
"exif-reader": "^1.0.1",
|
||||
"icc": "^0.0.2",
|
||||
"mocha": "^3.2.0",
|
||||
|
@ -434,4 +434,20 @@ namespace sharp {
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
Convert RGBA value to another colourspace
|
||||
*/
|
||||
std::vector<double> GetRgbaAsColourspace(std::vector<double> const rgba, VipsInterpretation const interpretation) {
|
||||
int const bands = static_cast<int>(rgba.size());
|
||||
if (bands < 3 || interpretation == VIPS_INTERPRETATION_sRGB || interpretation == VIPS_INTERPRETATION_RGB) {
|
||||
return rgba;
|
||||
} else {
|
||||
VImage pixel = VImage::new_matrix(1, 1);
|
||||
pixel.set("bands", bands);
|
||||
pixel = pixel.new_from_image(rgba);
|
||||
pixel = pixel.colourspace(interpretation, VImage::option()->set("source_space", VIPS_INTERPRETATION_sRGB));
|
||||
return pixel(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sharp
|
||||
|
@ -199,6 +199,11 @@ namespace sharp {
|
||||
*/
|
||||
VipsInterpretation GetInterpretation(std::string const typeStr);
|
||||
|
||||
/*
|
||||
Convert RGBA value to another colourspace
|
||||
*/
|
||||
std::vector<double> GetRgbaAsColourspace(std::vector<double> const rgba, VipsInterpretation const interpretation);
|
||||
|
||||
} // namespace sharp
|
||||
|
||||
#endif // SRC_COMMON_H_
|
||||
|
@ -470,6 +470,8 @@ class PipelineWorker : public Nan::AsyncWorker {
|
||||
if (baton->background[3] < 255.0 || HasAlpha(image)) {
|
||||
background.push_back(baton->background[3] * multiplier);
|
||||
}
|
||||
// Ensure background colour uses correct colourspace
|
||||
background = sharp::GetRgbaAsColourspace(background, image.interpretation());
|
||||
// Add non-transparent alpha channel, if required
|
||||
if (baton->background[3] < 255.0 && !HasAlpha(image)) {
|
||||
image = image.bandjoin(
|
||||
@ -538,6 +540,8 @@ class PipelineWorker : public Nan::AsyncWorker {
|
||||
if (baton->background[3] < 255.0 || HasAlpha(image)) {
|
||||
background.push_back(baton->background[3] * multiplier);
|
||||
}
|
||||
// Ensure background colour uses correct colourspace
|
||||
background = sharp::GetRgbaAsColourspace(background, image.interpretation());
|
||||
// Add non-transparent alpha channel, if required
|
||||
if (baton->background[3] < 255.0 && !HasAlpha(image)) {
|
||||
image = image.bandjoin(
|
||||
@ -689,14 +693,13 @@ class PipelineWorker : public Nan::AsyncWorker {
|
||||
}
|
||||
image = image.extract_band(baton->extractChannel);
|
||||
}
|
||||
|
||||
// Convert image to sRGB, if not already
|
||||
if (sharp::Is16Bit(image.interpretation())) {
|
||||
image = image.cast(VIPS_FORMAT_USHORT);
|
||||
}
|
||||
if (image.interpretation() != baton->colourspace) {
|
||||
// Need to convert image
|
||||
image = image.colourspace(baton->colourspace);
|
||||
// Convert colourspace, pass the current known interpretation so libvips doesn't have to guess
|
||||
image = image.colourspace(baton->colourspace, VImage::option()->set("source_space", image.interpretation()));
|
||||
// Transform colours from embedded profile to output profile
|
||||
if (baton->withMetadata &&
|
||||
sharp::HasProfile(image) &&
|
||||
|
BIN
test/fixtures/cielab-dagams.tiff
vendored
Normal file
BIN
test/fixtures/cielab-dagams.tiff
vendored
Normal file
Binary file not shown.
BIN
test/fixtures/expected/embed-lab-into-rgba.png
vendored
Normal file
BIN
test/fixtures/expected/embed-lab-into-rgba.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.6 KiB |
1
test/fixtures/index.js
vendored
1
test/fixtures/index.js
vendored
@ -83,6 +83,7 @@ module.exports = {
|
||||
inputWebP: getPath('4.webp'), // http://www.gstatic.com/webp/gallery/4.webp
|
||||
inputWebPWithTransparency: getPath('5_webp_a.webp'), // http://www.gstatic.com/webp/gallery3/5_webp_a.webp
|
||||
inputTiff: getPath('G31D.TIF'), // http://www.fileformat.info/format/tiff/sample/e6c9a6e5253348f4aef6d17b534360ab/index.htm
|
||||
inputTiffCielab: getPath('cielab-dagams.tiff'), // https://github.com/lovell/sharp/issues/646
|
||||
inputGif: getPath('Crash_test.gif'), // http://upload.wikimedia.org/wikipedia/commons/e/e3/Crash_test.gif
|
||||
inputGifGreyPlusAlpha: getPath('grey-plus-alpha.gif'), // http://i.imgur.com/gZ5jlmE.gif
|
||||
inputSvg: getPath('check.svg'), // http://dev.w3.org/SVG/tools/svgweb/samples/svg-files/check.svg
|
||||
|
@ -22,7 +22,6 @@ describe('Embed', function () {
|
||||
});
|
||||
});
|
||||
|
||||
if (sharp.format.webp.output.buffer) {
|
||||
it('JPEG within WebP, to include alpha channel', function (done) {
|
||||
sharp(fixtures.inputJpg)
|
||||
.resize(320, 240)
|
||||
@ -39,7 +38,6 @@ describe('Embed', function () {
|
||||
fixtures.assertSimilar(fixtures.expected('embed-3-into-4.webp'), data, done);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
it('PNG with alpha channel', function (done) {
|
||||
sharp(fixtures.inputPngWithTransparency)
|
||||
@ -103,6 +101,23 @@ describe('Embed', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('embed TIFF in LAB colourspace onto RGBA background', function (done) {
|
||||
sharp(fixtures.inputTiffCielab)
|
||||
.resize(64, 128)
|
||||
.embed()
|
||||
.background({r: 255, g: 102, b: 0, alpha: 0.5})
|
||||
.png()
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(true, data.length > 0);
|
||||
assert.strictEqual('png', info.format);
|
||||
assert.strictEqual(64, info.width);
|
||||
assert.strictEqual(128, info.height);
|
||||
assert.strictEqual(4, info.channels);
|
||||
fixtures.assertSimilar(fixtures.expected('embed-lab-into-rgba.png'), data, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('Enlarge and embed', function (done) {
|
||||
sharp(fixtures.inputPngWithOneColor)
|
||||
.embed()
|
||||
|
Loading…
x
Reference in New Issue
Block a user