diff --git a/src/compression/webimage.js b/src/compression/webimage.js index a610e85e..f053de6e 100644 --- a/src/compression/webimage.js +++ b/src/compression/webimage.js @@ -29,12 +29,28 @@ export default class WebImageDecoder extends BaseDecoder { canvas = new OffscreenCanvas(imageBitmap.width, imageBitmap.height); } + // Draw the image onto the canvas to extract the pixel data. Note this + // always returns RGBA, even if the original image was RGB. const ctx = canvas.getContext('2d'); ctx.drawImage(imageBitmap, 0, 0); + const imageData = ctx.getImageData(0, 0, imageBitmap.width, imageBitmap.height).data; - // TODO: check how many samples per pixel we have, and return RGB/RGBA accordingly - // it seems like GDAL always encodes via RGBA which does not require a translation - - return ctx.getImageData(0, 0, imageBitmap.width, imageBitmap.height).data.buffer; + // Return the correct channels to the caller + const spp = fileDirectory.SamplesPerPixel || 4; + if (spp === 4) { + // RGBA, return as is + return imageData.buffer; + } else if (spp === 3) { + // RGB, remove alpha channel before returning + const rgb = new Uint8ClampedArray(imageBitmap.width * imageBitmap.height * 3); + for (let i = 0, j = 0; i < rgb.length; i += 3, j += 4) { + rgb[i ] = imageData[j ]; + rgb[i + 1] = imageData[j + 1]; + rgb[i + 2] = imageData[j + 2]; + } + return rgb.buffer; + } else { + throw new Error(`Unsupported SamplesPerPixel value: ${spp}`); + } } }