问题
当我们使用canva.drawImage绘制alpha<1的图片时,如果你想要使用canvas.getImageData来获取回图片的像素信息。这个时候你会发现你获取到的像素颜色信息,与你的原图片并不一致
问题根源
canvas 2d绘制半透明图片的时候,进行了alpha-premultiplication(alpha预乘)
解决方案
使用 WebGL 2 读取图像的准确字节值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<img src="你的图片路径" id="mask">
<script>
let image = document.getElementById('mask');
image.addEventListener('load', function () {
let canvas = document.createElement('canvas');
let ctx = canvas.getContext("2d");
canvas.width = this.width;
canvas.height = this.height;
ctx.drawImage(this, 0, 0);
let data = ctx.getImageData(0, 0, this.width, this.height).data;
// 经过alpha预乘处理,获取到的值与原图片不一致
console.log(data);
});
image.addEventListener('load', function () {
let canvas = document.createElement('canvas');
let gl = canvas.getContext("webgl2");
gl.activeTexture(gl.TEXTURE0);
let texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
const framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this);
gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
let data = new Uint8Array(this.width * this.height * 4);
gl.readPixels(0, 0, this.width, this.height, gl.RGBA, gl.UNSIGNED_BYTE, data);
// 获取到的像素数值与原图片一致!!!!
console.log(data);
});
</script>
</body>
</html>