gpt4 book ai didi

javascript - 将 Canvas 图像和 Canvas alpha 蒙版合并到 dataurl 生成的 png

转载 作者:数据小太阳 更新时间:2023-10-29 03:53:01 27 4
gpt4 key购买 nike

给定两个像素大小相同的 Canvas ,其中 canvas1 包含任意图像(jpg、png 等),canvas2 包含黑色和非黑色像素。

我想要实现的目标:使用第三个 canvas3 我想克隆 canvas1 并让每个黑色 canvas2 像素(可能包括黑色阈值)在 canvas3 中都是透明的

我已经有了这样一个可行的解决方案:

canvas3context.drawImage(canvas1,0,0);
var c3img = canvas3context.getImageData(0,0,canvas3.width,canvas3.height);
var c2img = canvas2context.getImageData(0,0,canvas2.width,canvas2.height);
loop(){
if(c2img i-th,i+1-th,i+2-th pixel is lower than threshold)
set c3img.data[i]=c3img.data[i+1]=c3img.data[i+2]=c3img.data[i+3]=0
}

上面(伪)代码的问题是,它很慢所以我的问题是:任何人都可以分享如何显着加快速度的想法?我考虑过 webgl,但我从未使用过它 - 所以我不知道着色器或为此所需的工具或术语。另一个想法是,也许我可以以某种方式非常快速地将 canvas2 转换为黑白(不仅仅是像上面那样修改循环中的每个像素)并使用混合模式来生成透明像素

非常感谢任何帮助

最佳答案

回答我自己的问题,我提供了一个将任意图像与黑白图像合并的解决方案。我仍然缺少的是如何为 Canvas 的一种颜色设置 alpha channel 。

我将问题分成几个部分并分别回答。

Question 1: How to convert a canvas into grayscale without iterating every pixel?

答案:使用“光度”混合模式将图像绘制到白色 Canvas 上

function convertCanvasToGrayscale(canvas){
var tmp = document.createElement('canvas');
tmp.width = canvas.width;
tmp.height = canvas.height;
var tmpctx = tmp.getContext('2d');

// conversion
tmpctx.globalCompositeOperation="source-over"; // default composite value
tmpctx.fillStyle="#FFFFFF";
tmpctx.fillRect(0,0,canvas.width,canvas.height);
tmpctx.globalCompositeOperation="luminosity";
tmpctx.drawImage(canvas,0,0);

// write converted back to canvas
ctx = canvas.getContext('2d');
ctx.globalCompositeOperation="source-over";
ctx.drawImage(tmp, 0, 0);
}

Question 2: How to convert a grayscale canvas into black&white without iterating every pixel?

答案:两次颜色减淡混合模式与颜色#FEFEFE 将完成这项工作

function convertGrayscaleCanvasToBlackNWhite(canvas){
var ctx = canvas.getContext('2d');

// in case the grayscale conversion is to bulky for ya
// darken the canvas bevore further black'nwhite conversion
//for(var i=0;i<3;i++){
// ctx.globalCompositeOperation = 'multiply';
// ctx.drawImage(canvas, 0, 0);
//}

ctx.globalCompositeOperation = 'color-dodge';
ctx.fillStyle = "rgba(253, 253, 253, 1)";
ctx.beginPath();
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fill();
ctx.globalCompositeOperation = 'color-dodge';
ctx.fillStyle = "rgba(253, 253, 253, 1)";
ctx.beginPath();
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fill();
}

注意:此函数假设您希望黑色区域保持黑色并且每个非黑色像素都变成白色!因此,没有黑色像素的灰度图像将变成全白我选择这个操作的原因是它在我的例子中效果更好并且只使用两个混合操作意味着它非常快 - 如果你想让更多的暗像素保持黑色并且更多的白色像素变成白色你可以使用注释的for循环来变暗事先的图像。因此,暗像素将变黑,而较亮的像素将变暗。当你增加黑色像素的数量时,使用颜色减淡将再次完成剩下的工作

Question 3: How to merge a Black&White canvas with another canvas without iterating every pixel?

答案:使用“乘法”混合模式

function getBlendedImageWithBlackNWhite(canvasimage, canvasbw){
var tmp = document.createElement('canvas');
tmp.width = canvasimage.width;
tmp.height = canvasimage.height;

var tmpctx = tmp.getContext('2d');

tmpctx.globalCompositeOperation = 'source-over';
tmpctx.drawImage(canvasimage, 0, 0);

// multiply means, that every white pixel gets replaced by canvasimage pixel
// and every black pixel will be left black
tmpctx.globalCompositeOperation = 'multiply';
tmpctx.drawImage(canvasbw, 0, 0);

return tmp;
}

Question 4: How to invert a Black&White canvas without iterating every pixel?

答案:使用“差异”混合模式

function invertCanvas(canvas){
var ctx = canvas.getContext("2d");

ctx.globalCompositeOperation = 'difference';
ctx.fillStyle = "rgba(255, 255, 255, 1)";
ctx.beginPath();
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fill();
}

现在可以将 Canvas 图像与 Canvas 蒙版“合并”

convertCanvasToGrayscale(canvasmask);
convertGrayscaleCanvasToBlackNWhite(canvasmask);
result = getBlendedImageWithBlackNWhite(canvasimage, canvasmask);

关于性能:显然,这些混合模式比修改每个像素要快得多,为了更快一点,可以根据需要将所有函数打包到一个函数中,并只回收一个 tmpcanvas——但这留给读者了^^

作为旁注:当您将上面的 getBlendedImageWithBlackNWhite 结果与同一图像进行比较时,我测试了生成的 png 的大小有何不同,但通过迭代每个像素并设置 alpha channel ,黑色区域变得透明大小上的差异几乎没有,因此如果您真的不需要 alpha 掩码,那么每个黑色像素都应该是透明的信息可能足以进行进一步处理

注意:可以使用 invertCanvas() 函数反转黑白的含义

如果你想知道更多关于我为什么使用这些混合模式或者混合模式是如何工作的你应该检查它们背后的数学原理——恕我直言,如果你不知道它们是如何工作的,你就无法开发这样的函数: math behind blend modes canvas composition standard including a bit math

需要一个示例 - 找出不同之处:http://jsfiddle.net/C3fp4/1/

关于javascript - 将 Canvas 图像和 Canvas alpha 蒙版合并到 dataurl 生成的 png,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24740899/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com