处理canvas绘制alpha小于1的图片时,alpha预乘问题

问题

当我们使用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>

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值