Estoy tratando de escalar una imagen con píxeles transparentes usando CanvasRenderingContext2D.drawImage, pero cada vez que dibujo la imagen, lo que obtengo es tanto la imagen del tamaño original como la versión escalada dibujada en el lienzo. Aquí hay un código para reproducir la falla:
<canvas id="cvs" width=200 height=100></canvas> const canvas = document.getElementById('cvs'); const ctx = canvas.getContext('2d'); ctx.imageSmoothingEnabled = false; const imageData = ctx.createImageData(100, 50); const data = imageData.data; for (var i = 0; i < data.length; i += 4) { if (i % 400 > 360) { data[i] = 255; data[i + 1] = 0; data[i + 2] = 0; data[i + 3] = 255; } else { data[i] = 0; data[i + 1] = 0; data[i + 2] = 0; data[i + 3] = 0; // Change this to 255 to get rid of the glitch } } ctx.putImageData(imageData, 0, 0); ctx.drawImage(canvas, 0, 0, 100, 50, 0, 0, 200, 100);https://jsfiddle.net/o4sv6qhb/2/
No entiendo por qué sucede esto. Si no uso píxeles transparentes, el problema desaparece.
Supongo que una solución alternativa sería llenar los píxeles de la imagen de tamaño final directamente y no usar la escala de drawImage, pero preferiría no tener que hacer esto.
Estás dibujando en el lienzo dos veces, una vez con putImageData a una escala de 1:1 píxeles y luego otra vez usando drawImage en tu versión ampliada.
El segundo dibujo se superpone al primero, por lo que si no tiene píxeles transparentes, simplemente no puede ver la imagen original porque se está pintando.
Pero si tiene píxeles transparentes, la imagen más grande no se dibuja sobre la imagen de atrás y se muestra la imagen anterior.
Si solo desea la imagen de su comando drawImage , puede intentar crear un lienzo separado para pintar sus datos de imagen y luego dibujar ese lienzo en el primero, pero ampliado.
const canvas = document.getElementById('cvs'); // create a second hidden canvas/context pair const offscreenCanvas = document.createElement('canvas'); const hiddenContext - offscreenCanvas.getContext('2d'); const ctx = canvas.getContext('2d'); ctx.imageSmoothingEnabled = false; const imageData = ctx.createImageData(100, 50); const data = imageData.data; for (var i = 0; i < data.length; i += 4) { if (i % 400 > 360) { data[i] = 255; data[i + 1] = 0; data[i + 2] = 0; data[i + 3] = 255; } else { data[i] = 0; data[i + 1] = 0; data[i + 2] = 0; data[i + 3] = 0; // Change this to 255 to get rid of the glitch } } // draw to the hidden canvas hiddenContext.putImageData(imageData, 0, 0); // draw the hidden canvas content to the visible one and scale ctx.drawImage(offscreenCanvas, 0, 0, 100, 50, 0, 0, 200, 100);