如何在未知像素坐标且不操作图像数据的前提下将半透明像素转为完全不透明?
如何在未知像素坐标且不操作图像数据的前提下将半透明像素转为完全不透明?
嘿,这个问题挺有意思的!你想要把所有带透明度(alpha>0)的像素直接转成完全不透明的白色,还不想用getImageData/putImageData,也不知道目标区域的坐标对吧?我刚好有个办法能搞定,利用Canvas的合成模式和临时画布就能实现,不用碰图像数据,也不用猜坐标。
看你的代码,现在画布上的状态是:原来的白色方块被source-in改成了半透明红色,其他区域还是透明(Canvas的CSS背景是独立的,不会被绘制操作影响)。我们可以这样恢复成纯白方块:
实现步骤
- 先创建一个临时画布,把当前画布的内容备份下来——这一步是为了记住哪些区域有像素(也就是那个方块的位置)。
- 把原画布整个填充成纯白不透明,用
copy模式确保覆盖所有区域。 - 再用
destination-in合成模式,把临时画布的内容画回原画布——这个模式会只保留原画布中与临时画布有内容的重叠区域,其他区域变回透明,刚好就留下了纯白不透明的方块。
修改后的代码
把你代码里的// now what ???替换成以下内容:
// now what ??? // 步骤1:创建临时画布备份当前状态 const tempCanvas = document.createElement('canvas'); tempCanvas.width = canvas.width; tempCanvas.height = canvas.height; const tempCtx = tempCanvas.getContext('2d'); tempCtx.drawImage(canvas, 0, 0); // 步骤2:用copy模式填充整个画布为纯白不透明 ctx.fillStyle = '#fff'; ctx.globalCompositeOperation = 'copy'; ctx.fillRect(0, 0, canvas.width, canvas.height); // 步骤3:用destination-in模式,把临时画布的内容画回来,只保留有像素的区域 ctx.globalCompositeOperation = 'destination-in'; ctx.drawImage(tempCanvas, 0, 0); // 恢复默认的合成模式,方便后续操作 ctx.globalCompositeOperation = 'source-over';
原理说明
copy模式会直接用新的填充内容覆盖整个画布,所以这一步之后整个画布都是纯白不透明,Canvas的CSS背景暂时看不到了。destination-in模式的作用是:只保留目标画布(现在是纯白)中与源画布(临时画布的半透红方块)有重叠的部分——也就是只有原来方块的位置会保留纯白,其他区域因为临时画布是透明的,所以会被清除成透明,这样CSS背景又能显示出来了。- 整个过程完全不用知道方块的坐标,也没用到
getImageData/putImageData,完美符合你的需求!
备注:内容来源于stack exchange,提问作者user29889977
相关产品推荐
相关产品推荐

