Company logo
  • Empleos
  • Bootcamp
  • Acerca de nosotros
  • Para profesionales
    • Inicio
    • Empleos
    • Cursos y retos
    • Preguntas
    • Profesores
    • Bootcamp
  • Para empresas
    • Inicio
    • Nuestro proceso
    • Planes
    • Pruebas
    • Nómina
    • Blog
    • Comercial
    • Calculadora

0

45
Vistas
Why image data encoded into base64 decodes back with wrong values?

I'm trying to convert an array into a base64 string. And then back again. I've made a simple example with a sample array looking like this: [0, 1, 2, 3, 0, 1, 2, 3] and converting with .toDataURL() in canvas. But by some reason, when I read base64 string back and apply it to the canvas it returns a different image data: [0, 0, 0, 3, 0, 0, 0, 3].

Why this happens?

Example:

const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');

const array = new Uint8ClampedArray([0, 1, 2, 3, 0, 1, 2, 3]);
const initialImageData = new ImageData(array, 2, 1);

ctx.putImageData(initialImageData, 0, 0);
const dataURL = canvas.toDataURL();

console.log(dataURL); // data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAABCAYAAAD0In+KAAAAAXNSR0IArs4c6QAAAA9JREFUGFdjZGBgYGYAAgAAIQAFoFclWQAAAABJRU5ErkJggg==

const img = new Image();
img.onload = () => {
    canvas.width = 2;
    canvas.height = 1;
    ctx.drawImage(img, 0, 0);
    const imageData = ctx.getImageData(0, 0, 2, 1);
    console.log(imageData.data); // [0, 0, 0, 3, 0, 0, 0, 3]
}
img.src = dataURL;
7 months ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Looks like you've been caught by this gotcha in the Canvas implementation:

Warning: Due to the lossy nature of converting to and from premultiplied alpha color values, pixels that have just been set using putImageData() might be returned to an equivalent getImageData() as different values.

(emphasis mine)

The Uint8ClampedArray you pass in is in format [r, g, b, a] and the Alpha (a) component is extremely important. In your test you've supplied an Alpha of 3 and it appears the browser is choosing to "optimize" the other pixels to 0.

Try a full-opacity value of a and it all works fine:

const array = new Uint8ClampedArray([0, 1, 2, 255, 0, 1, 2, 255]);

...

console.log(imageData.data); // [0, 1, 2, 255, 0, 1, 2, 255]
7 months ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos