From 76450f7e2d7a55220d5d01faf45df0c33c38aba6 Mon Sep 17 00:00:00 2001 From: Chris Barber Date: Fri, 23 Oct 2015 14:05:00 -0500 Subject: [PATCH] Added bgColor support when removing alpha from image. --- README.md | 26 ++++++++++++++++++++++++++ lib/bitpacker.js | 19 ++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5bf32a0..143030e 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,8 @@ As input any color type is accepted (grayscale, rgb, palette, grayscale with alp - `filterType` - png filtering method for scanlines (default: -1 => auto, accepts array of numbers 0-4) - `colorType` - the output colorType - see constants. 2 = color, no alpha, 6 = color & alpha. Default currently 6, but in the future may calculate best mode. - `inputHasAlpha` - whether the input bitmap has 4 bits per pixel (rgb and alpha) or 3 (rgb - no alpha). +- `bgColor` - an object containing red, green, and blue values between 0 and 255 +that is used when an rgba image is converted to rgb (default: 255,255,255) ### Event "metadata" @@ -206,6 +208,30 @@ Buffer of image pixel data. Every pixel consists 4 bytes: R, G, B, A (opacity). ### Property: gamma Gamma of image (0 if not specified) +## Converting RGBA to RGB + +When removing the alpha channel from an image, there needs to be a background color to correctly +convert each pixel's transparency to the appropriate RGB value. By default, pngjs will flatten +the image against a white background. You can override this in the options: + +```js +var fs = require('fs'), + PNG = require('pngjs').PNG; + +fs.createReadStream('in.png') + .pipe(new PNG({ + colorType: 2, + bgColor: { + red: 0, + green: 255, + blue: 0 + } + })) + .on('parsed', function() { + this.pack().pipe(fs.createWriteStream('out.png')); + }); +``` + # Sync API ## PNG.sync diff --git a/lib/bitpacker.js b/lib/bitpacker.js index 6b8eb2a..0267c6e 100644 --- a/lib/bitpacker.js +++ b/lib/bitpacker.js @@ -17,6 +17,17 @@ module.exports = function(data, width, height, options) { var inIndex = 0; var outIndex = 0; + var bgColor = options.bgColor || {}; + if (bgColor.red === undefined) { + bgColor.red = 255; + } + if (bgColor.green === undefined) { + bgColor.green = 255; + } + if (bgColor.blue === undefined) { + bgColor.blue = 255; + } + for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { var red = data[inIndex]; @@ -26,6 +37,12 @@ module.exports = function(data, width, height, options) { var alpha; if (options.inputHasAlpha) { alpha = data[inIndex + 3]; + if (!outHasAlpha) { + alpha /= 255; + red = Math.min(Math.max(Math.round((1 - alpha) * bgColor.red + alpha * red), 0), 255); + green = Math.min(Math.max(Math.round((1 - alpha) * bgColor.green + alpha * green), 0), 255); + blue = Math.min(Math.max(Math.round((1 - alpha) * bgColor.blue + alpha * blue), 0), 255); + } } else { alpha = 255; @@ -44,4 +61,4 @@ module.exports = function(data, width, height, options) { } return outData; -}; \ No newline at end of file +};