Necesito leer el valor de transparencia para cada píxel de un PNG enviado por el usuario, en el front-end.
En este momento, estoy bloqueando el envío del formulario y convierto el PNG en la entrada del archivo en un objeto FileReader. Ahora estaba pensando que simplemente podría leer los valores de transparencia de esos datos. Por ejemplo, convertí a ArrayBuffer y luego a Uint8Array, y esa es una gran variedad de enteros cuyos valores van de 0 a 255, pero no parecen los colores correctos.
Luego leí que en realidad debes mostrar el PNG en un lienzo HTML5 para hacer esto.
el búfer png no contiene los datos de píxeles de una manera legible, está comprimido para que no pueda leerlo como le gustaría. tiene que obtener los píxeles de alguna manera, la forma más sencilla es usar createImageBitmap (archivo) para convertirlo en un mapa de bits y luego usar OffscreenCanvas para pintar el mapa de bits y leerlo usando getImageData . De esta manera, puede leer más que solo pngs. .. y también usándolo en subprocesos de trabajo
// simulate getting a file you would get from eg file input (1x1 pixel) fetch('data:;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==') .then(r => r.blob()) .then(createImageBitmap) .then(readData) /** @param {ImageBitmap} bitmap */ function readData (bitmap) { const { width: w, height: h } = bitmap const canvas = new OffscreenCanvas(w, h) const ctx = canvas.getContext('2d') ctx.drawImage(bitmap, 0, 0) const pixels = ctx.getImageData(0, 0, w, h).data // read alpha channel for (let i = 0; i < pixels.length; i += 4) { console.log(pixels[i + 3]) } }PNG no contiene los datos de la imagen sin procesar, pero está comprimido. Para decodificarlo, necesitas hacer algunos cálculos complejos. Cárguelo en un <canvas> y deje que el navegador haga la decodificación:
<canvas id="myCanvas"></canvas> <input type="file" accept="image/png, image/gif, image/jpeg" id="myFileInput" /> <script> const canvas = document.getElementById('myCanvas'); const context = canvas.getContext("2d"); const fileInput = document.getElementById('myFileInput'); fileInput.onchange = function(changeEvent) { const files = changeEvent.target.files; const file = files[0]; const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = function(loadEvent){ const image = new Image(); image.src = loadEvent.target.result; canvas.width = image.width; canvas.height = image.height; context.drawImage(image, 0, 0); const imageData = context.getImageData(0, 0, image.width, image.height); console.log(imageData) // see https://stackoverflow.com/a/667074/17870699 } }; </script>