From 2675b2265bdcf913e1bd47be48bc76de0bb930f9 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Sat, 30 Jan 2016 22:23:17 +0000 Subject: [PATCH] Ensure 16-bit input images embed onto alpha background Support gamma correction of images with alpha channel Favour shrink over affine when reducing by integral factor --- docs/changelog.md | 11 ++++++++ package.json | 10 +++---- src/metadata.h | 0 src/operations.cc | 16 ++++++++++- src/operations.h | 5 ++++ src/pipeline.cc | 28 +++++++++++++------- src/pipeline.h | 0 test/fixtures/expected/embed-16bit-rgba.png | Bin 0 -> 755 bytes test/fixtures/expected/gamma-alpha.jpg | Bin 4226 -> 4612 bytes test/unit/embed.js | 15 +++++++++++ 10 files changed, 70 insertions(+), 15 deletions(-) mode change 100755 => 100644 package.json mode change 100755 => 100644 src/metadata.h mode change 100755 => 100644 src/pipeline.h create mode 100644 test/fixtures/expected/embed-16bit-rgba.png diff --git a/docs/changelog.md b/docs/changelog.md index 41a67fd7..690e7f56 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,9 +2,20 @@ ### v0.13 - "*mind*" +* Switch from libvips' C to C++ bindings, requires upgrade to v8.2.2. + [#299](https://github.com/lovell/sharp/issues/299) + * Control number of open files in libvips' cache; breaks existing `cache` behaviour. [#315](https://github.com/lovell/sharp/issues/315) +* Ensure 16-bit input images can be embedded onto a transparent background. + [#340](https://github.com/lovell/sharp/issues/340) + [@janaz](https://github.com/janaz) + +* Small optimisation when reducing by an integral factor to favour shrink over affine. + +* Add support for gamma correction of images with an alpha channel. + ### v0.12 - "*look*" #### v0.12.2 - 16th January 2016 diff --git a/package.json b/package.json old mode 100755 new mode 100644 index 91fef593..6742734b --- a/package.json +++ b/package.json @@ -47,11 +47,11 @@ "vips" ], "dependencies": { - "bluebird": "^3.1.1", + "bluebird": "^3.1.5", "color": "^0.11.1", "nan": "^2.2.0", "semver": "^5.1.0", - "request": "^2.67.0", + "request": "^2.69.0", "tar": "^2.2.1" }, "devDependencies": { @@ -60,10 +60,10 @@ "exif-reader": "^1.0.0", "icc": "^0.0.2", "istanbul": "^0.4.2", - "mocha": "^2.3.4", - "mocha-jshint": "^2.2.6", + "mocha": "^2.4.5", + "mocha-jshint": "^2.3.0", "node-cpplint": "^0.4.0", - "rimraf": "^2.5.0", + "rimraf": "^2.5.1", "bufferutil": "^1.2.1" }, "license": "Apache-2.0", diff --git a/src/metadata.h b/src/metadata.h old mode 100755 new mode 100644 diff --git a/src/operations.cc b/src/operations.cc index 1a6bb4f0..16fdec9e 100644 --- a/src/operations.cc +++ b/src/operations.cc @@ -102,11 +102,25 @@ namespace sharp { return image; } + /* + * Gamma encoding/decoding + */ + VImage Gamma(VImage image, double const exponent) { + if (HasAlpha(image)) { + // Separate alpha channel + VImage imageWithoutAlpha = image.extract_band(0, + VImage::option()->set("n", image.bands() - 1)); + VImage alpha = image[image.bands() - 1]; + return imageWithoutAlpha.gamma(VImage::option()->set("exponent", exponent)).bandjoin(alpha); + } else { + return image.gamma(VImage::option()->set("exponent", exponent)); + } + } + /* * Gaussian blur (use sigma <0 for fast blur) */ VImage Blur(VImage image, double const sigma) { - VImage blurred; if (sigma < 0.0) { // Fast, mild blur - averages neighbouring pixels VImage blur = VImage::new_matrixv(3, 3, diff --git a/src/operations.h b/src/operations.h index 3ce63036..ba69b25d 100644 --- a/src/operations.h +++ b/src/operations.h @@ -18,6 +18,11 @@ namespace sharp { */ VImage Normalize(VImage image); + /* + * Gamma encoding/decoding + */ + VImage Gamma(VImage image, double const exponent); + /* * Gaussian blur. Use sigma of -1 for fast blur. */ diff --git a/src/pipeline.cc b/src/pipeline.cc index c1d65c84..b5340d12 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -43,6 +43,7 @@ using vips::VError; using sharp::Composite; using sharp::Normalize; +using sharp::Gamma; using sharp::Blur; using sharp::Sharpen; @@ -425,7 +426,8 @@ class PipelineWorker : public AsyncWorker { } // Calculate maximum alpha value based on input image pixel depth - double maxAlpha = (image.format() == VIPS_FORMAT_USHORT) ? 65535.0 : 255.0; + bool is16Bit = (image.format() == VIPS_FORMAT_USHORT); + double maxAlpha = is16Bit ? 65535.0 : 255.0; // Flatten image to remove alpha channel if (baton->flatten && HasAlpha(image)) { @@ -449,8 +451,8 @@ class PipelineWorker : public AsyncWorker { } // Gamma encoding (darken) - if (baton->gamma >= 1 && baton->gamma <= 3 && !HasAlpha(image)) { - image = image.gamma(VImage::option()->set("exponent", 1.0 / baton->gamma)); + if (baton->gamma >= 1 && baton->gamma <= 3) { + image = Gamma(image, 1.0 / baton->gamma); } // Convert to greyscale (linear, therefore after gamma encoding, if any) @@ -541,10 +543,6 @@ class PipelineWorker : public AsyncWorker { // Crop/embed if (image.width() != baton->width || image.height() != baton->height) { if (baton->canvas == Canvas::EMBED) { - // Add non-transparent alpha channel, if required - if (baton->background[3] < 255.0 && !HasAlpha(image)) { - image = image.bandjoin(VImage::black(image.width(), image.height()).invert()); - } // Scale up 8-bit values to match 16-bit input image double multiplier = (image.interpretation() == VIPS_INTERPRETATION_RGB16) ? 256.0 : 1.0; // Create background colour @@ -557,6 +555,12 @@ class PipelineWorker : public AsyncWorker { if (baton->background[3] < 255.0 || HasAlpha(image)) { background.push_back(baton->background[3] * multiplier); } + // Add non-transparent alpha channel, if required + if (baton->background[3] < 255.0 && !HasAlpha(image)) { + VImage alpha = VImage::new_matrix(image.width(), image.height()) + .new_from_image(baton->background[3] * multiplier); + image = image.bandjoin(alpha); + } // Embed int left = static_cast(round((baton->width - image.width()) / 2)); int top = static_cast(round((baton->height - image.height()) / 2)); @@ -639,11 +643,17 @@ class PipelineWorker : public AsyncWorker { // Reverse premultiplication after all transformations: if (shouldPremultiplyAlpha) { image = image.unpremultiply(VImage::option()->set("max_alpha", maxAlpha)); + // Cast pixel values to integer + if (is16Bit) { + image = image.cast(VIPS_FORMAT_USHORT); + } else { + image = image.cast(VIPS_FORMAT_UCHAR); + } } // Gamma decoding (brighten) - if (baton->gamma >= 1 && baton->gamma <= 3 && !HasAlpha(image)) { - image = image.gamma(VImage::option()->set("exponent", baton->gamma)); + if (baton->gamma >= 1 && baton->gamma <= 3) { + image = Gamma(image, baton->gamma); } // Apply normalization - stretch luminance to cover full dynamic range diff --git a/src/pipeline.h b/src/pipeline.h old mode 100755 new mode 100644 diff --git a/test/fixtures/expected/embed-16bit-rgba.png b/test/fixtures/expected/embed-16bit-rgba.png new file mode 100644 index 0000000000000000000000000000000000000000..70e3f3655c8ac088d3120c8ca620e79f371b3fc7 GIT binary patch literal 755 zcmV$j4o4DU>!WRRNW91$(#mkhaojes3b-N`Mf8v$Gm@cIF`nZy-ru;PsBd z=kv)dY^DWzdwbzDoWMSy2nvWnz!M&(X`n=LDMu8iw_`4pKx+=0bMU+V#2GiaG3=h4oBR}dEvI)=&$vo zrMJKt91O#NrfI0vboBJ(;BraeI1!=HU71y&gY_`AnzA(x8WB<=C=3@c@M8euwsDlp zWu((ObiDypy@%D+pc0Kfo@3=Qf5kqJFRtsly#8+e^KNSwF!5`F!NK=X)j=ealS(u? z7GY&xNdN$No|ggGw!dx5Te+=CUDwfWw-E{rAQpSBjEsz2sr*{0)oStO3Cus|!7 l%D*fAJ*H_!G)=o!`A?prFeAkNg2?~?002ovPDHLkV1gYbRjdF2 literal 0 HcmV?d00001 diff --git a/test/fixtures/expected/gamma-alpha.jpg b/test/fixtures/expected/gamma-alpha.jpg index 08b54565cb8562b5bdbef3f516db4b267fe9b05a..aabde8a921f4817f0f642670dbf44bda76a49c36 100644 GIT binary patch delta 4293 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 Re 0); + assert.strictEqual('png', info.format); + assert.strictEqual(32, info.width); + assert.strictEqual(16, info.height); + fixtures.assertSimilar(fixtures.expected('embed-16bit-rgba.png'), data, done); + }); + }); + it('Enlarge and embed', function(done) { sharp(fixtures.inputPngWithOneColor) .embed()