diff --git a/src/common.cc b/src/common.cc index ee9519d20..3794bcdfe 100644 --- a/src/common.cc +++ b/src/common.cc @@ -602,4 +602,40 @@ namespace sharp { } } + /* + Apply the alpha channel to a given colour + */ + std::tuple> ApplyAlpha(VImage image, double colour[4]) { + // Scale up 8-bit values to match 16-bit input image + double const multiplier = sharp::Is16Bit(image.interpretation()) ? 256.0 : 1.0; + // Create alphaColour colour + std::vector alphaColour; + if (image.bands() > 2) { + alphaColour = { + multiplier * colour[0], + multiplier * colour[1], + multiplier * colour[2] + }; + } else { + // Convert sRGB to greyscale + alphaColour = { multiplier * ( + 0.2126 * colour[0] + + 0.7152 * colour[1] + + 0.0722 * colour[2]) + }; + } + // Add alpha channel to alphaColour colour + if (colour[3] < 255.0 || HasAlpha(image)) { + alphaColour.push_back(colour[3] * multiplier); + } + // Ensure alphaColour colour uses correct colourspace + alphaColour = sharp::GetRgbaAsColourspace(alphaColour, image.interpretation()); + // Add non-transparent alpha channel, if required + if (colour[3] < 255.0 && !HasAlpha(image)) { + image = image.bandjoin( + VImage::new_matrix(image.width(), image.height()).new_from_image(255 * multiplier)); + } + return std::make_tuple(image, alphaColour); + } + } // namespace sharp diff --git a/src/common.h b/src/common.h index 5ac1cf13c..4b31008c4 100644 --- a/src/common.h +++ b/src/common.h @@ -255,6 +255,11 @@ namespace sharp { */ std::vector GetRgbaAsColourspace(std::vector const rgba, VipsInterpretation const interpretation); + /* + Apply the alpha channel to a given colour + */ + std::tuple> ApplyAlpha(VImage image, double colour[4]); + } // namespace sharp #endif // SRC_COMMON_H_ diff --git a/src/pipeline.cc b/src/pipeline.cc index a1e414fce..4c6d2bbfd 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -421,35 +421,8 @@ class PipelineWorker : public Nan::AsyncWorker { // Crop/embed if (image.width() != baton->width || image.height() != baton->height) { if (baton->canvas == Canvas::EMBED) { - // Scale up 8-bit values to match 16-bit input image - double const multiplier = sharp::Is16Bit(image.interpretation()) ? 256.0 : 1.0; - // Create background colour std::vector background; - if (image.bands() > 2) { - background = { - multiplier * baton->background[0], - multiplier * baton->background[1], - multiplier * baton->background[2] - }; - } else { - // Convert sRGB to greyscale - background = { multiplier * ( - 0.2126 * baton->background[0] + - 0.7152 * baton->background[1] + - 0.0722 * baton->background[2]) - }; - } - // Add alpha channel to background colour - 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( - VImage::new_matrix(image.width(), image.height()).new_from_image(255 * multiplier)); - } + std::tie(image, background) = sharp::ApplyAlpha(image, baton->background); // Embed @@ -511,35 +484,9 @@ class PipelineWorker : public Nan::AsyncWorker { // Extend edges if (baton->extendTop > 0 || baton->extendBottom > 0 || baton->extendLeft > 0 || baton->extendRight > 0) { - // Scale up 8-bit values to match 16-bit input image - double const multiplier = sharp::Is16Bit(image.interpretation()) ? 256.0 : 1.0; - // Create background colour std::vector background; - if (image.bands() > 2) { - background = { - multiplier * baton->background[0], - multiplier * baton->background[1], - multiplier * baton->background[2] - }; - } else { - // Convert sRGB to greyscale - background = { multiplier * ( - 0.2126 * baton->background[0] + - 0.7152 * baton->background[1] + - 0.0722 * baton->background[2]) - }; - } - // Add alpha channel to background colour - 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( - VImage::new_matrix(image.width(), image.height()).new_from_image(255 * multiplier)); - } + std::tie(image, background) = sharp::ApplyAlpha(image, baton->background); + // Embed baton->width = image.width() + baton->extendLeft + baton->extendRight; baton->height = image.height() + baton->extendTop + baton->extendBottom;