diff --git a/src/internal/storedPixelDataToCanvasImageDataPseudocolorLUT.js b/src/internal/storedPixelDataToCanvasImageDataPseudocolorLUT.js index 8f60b193..dafb7b57 100644 --- a/src/internal/storedPixelDataToCanvasImageDataPseudocolorLUT.js +++ b/src/internal/storedPixelDataToCanvasImageDataPseudocolorLUT.js @@ -33,7 +33,44 @@ function storedPixelDataToCanvasImageDataPseudocolorLUT (image, grayscaleLut, co clut = colorLut; } - if (minPixelValue < 0) { + // Finds the grayscale of 4 channels color image data by calculating the relative luminance value + if (image.color && ((image.width * image.height * 4) === numPixels)) { + if (minPixelValue < 0) { + while (storedPixelDataIndex < numPixels) { + const rValue = pixelData[storedPixelDataIndex++]; + const gValue = pixelData[storedPixelDataIndex++]; + const bValue = pixelData[storedPixelDataIndex++]; + + storedPixelDataIndex++; // The pixel data has 4 channels + + const luminance = getRelativeLuminance(rValue, gValue, bValue); + + grayscale = grayscaleLut[luminance + (-minPixelValue)]; + rgba = clut[grayscale]; + canvasImageDataData[canvasImageDataIndex++] = rgba[0]; + canvasImageDataData[canvasImageDataIndex++] = rgba[1]; + canvasImageDataData[canvasImageDataIndex++] = rgba[2]; + canvasImageDataData[canvasImageDataIndex++] = rgba[3]; + } + } else { + while (storedPixelDataIndex < numPixels) { + const rValue = pixelData[storedPixelDataIndex++]; + const gValue = pixelData[storedPixelDataIndex++]; + const bValue = pixelData[storedPixelDataIndex++]; + + storedPixelDataIndex++; // The pixel data has 4 channels + + const luminance = getRelativeLuminance(rValue, gValue, bValue); + + grayscale = grayscaleLut[luminance]; + rgba = clut[grayscale]; + canvasImageDataData[canvasImageDataIndex++] = rgba[0]; + canvasImageDataData[canvasImageDataIndex++] = rgba[1]; + canvasImageDataData[canvasImageDataIndex++] = rgba[2]; + canvasImageDataData[canvasImageDataIndex++] = rgba[3]; + } + } + } else if (minPixelValue < 0) { while (storedPixelDataIndex < numPixels) { grayscale = grayscaleLut[pixelData[storedPixelDataIndex++] + (-minPixelValue)]; rgba = clut[grayscale]; @@ -56,4 +93,17 @@ function storedPixelDataToCanvasImageDataPseudocolorLUT (image, grayscaleLut, co image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start; } +/** + * Calculates the relative luminance value from the RGB component values + * @param {Number} rValue R component value in RGB + * @param {Number} gValue G component value in RGB + * @param {Number} bValue B component value in RGB + * + * @returns {Number} The relative luminance value + */ +function getRelativeLuminance (rValue, gValue, bValue) { + // Calculate relative luminance can be calculated from linear RGB components + return Math.round(0.2126 * rValue + 0.7152 * gValue + 0.0722 * bValue); +} + export default storedPixelDataToCanvasImageDataPseudocolorLUT; diff --git a/test/internal/storedPixelDataToCanvasImageDataPseudocolorLUT_test.js b/test/internal/storedPixelDataToCanvasImageDataPseudocolorLUT_test.js index 4886637c..0e1be1c2 100644 --- a/test/internal/storedPixelDataToCanvasImageDataPseudocolorLUT_test.js +++ b/test/internal/storedPixelDataToCanvasImageDataPseudocolorLUT_test.js @@ -36,4 +36,33 @@ describe('storedPixelDataToCanvasImageDataPseudocolorLUT', function () { this.canvasImageData.should.be.deep.equal([4, 4, 1, 2, 7, 7, 2, 0]); }); + + describe('Color 4 Byte image', function () { + before(function () { + this.image.color = true; + this.grayscaleLut = [0, 1, 2, 3, 4, 5, 6, 7]; + this.colorLut = [[1, 2, 3, 4], [4, 4, 1, 2], [7, 7, 2, 0], [10, 10, 5, 6], [1, 2, 6, 5], [11, 11, 8, 9], [1, 2, 9, 8], [14, 14, 12, 13]]; + this.image.getPixelData = function () { + return [0, 1, 2, 3, 4, 5, 6, 7]; + }; + this.image.width = 2; + this.image.height = 1; + }); + + it('should get the values from colorLUT for color 4 byte image without the minPixel offset when minPixelValue == 0', function () { + this.image.minPixelValue = 0; + + storedPixelDataToCanvasImageDataPseudocolorLUT(this.image, this.grayscaleLut, this.colorLut, this.canvasImageData); + + this.canvasImageData.should.be.deep.equal([4, 4, 1, 2, 11, 11, 8, 9]); + }); + + it('should get the values from colorLUT for color 4 byte image with the minPixel offset when minPixelValue < 0', function () { + this.image.minPixelValue = -1; + + storedPixelDataToCanvasImageDataPseudocolorLUT(this.image, this.grayscaleLut, this.colorLut, this.canvasImageData); + + this.canvasImageData.should.be.deep.equal([7, 7, 2, 0, 1, 2, 9, 8]); + }); + }); });