Mouagip
Mouagip

Reputation: 5319

HTML canvas returns "off-by-some" bytes from getImageData

I found that getImageData of an HTML canvas seems to return incorrect byte values.

I generated a 1x1 px image with the following Python code:

from PIL import Image
import numpy as np

a = np.array([[[12, 187, 146, 62]]], dtype=np.uint8)
Image.fromarray(a).save('image.png')

I converted the image to base64 to include it in this code snippet:

let image = document.createElement('img');
image.addEventListener('load', () => {
  let canvas = document.createElement('canvas');
  let ctx = canvas.getContext("2d");
  canvas.width = image.width;
  canvas.height = image.height;
  ctx.drawImage(image, 0, 0);
  let data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
  document.body.innerHTML = data;
});

image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4nGPg2T3JDgADyAGYmiSbAQAAAABJRU5ErkJggg==";

When run in Firefox, it shows 12,189,148,62. In Chromium it shows 12,185,144,62. But the original values are 12,187,146,62.

Can anyone explain this?

Upvotes: 4

Views: 328

Answers (1)

Blindman67
Blindman67

Reputation: 54026

Firefox pre-multiplication rounding error

I can confirm that FF (Firefox) does indeed return the pixel value as [12,189,148,62]

When rendering to the canvas pixels are processed according to the value of globalCompositeOperation which defaults to "source-over". The calculation is performed on pre multiplied alpha values for which FF seams to be rounding incorrectly.

Note that turning off alpha canvas.getContext("2d", {alpha: false}) for CanvasRenderingContext2D the resulting pixels are FF [3,46,36,255] and Chrome [3,45,35,255].

Chrome has the correct values as shown in the following snippet.

// correct pre mult alpha 
console.log([12,187,146].map(c => Math.round(c * 62 / 255)) + "");

FF is rounding up for some reason and I would consider this a bug

This rounding error (in FF) is then effecting the result of "source-over" compositing when alpha: true resulting in the higher than expected values.

For more information on compositing W3C Compositing and Blending

Fix?

I can not suggest a fix, only to say that Chrome is rendering the image correctly, while FF is not.

Upvotes: 1

Related Questions