Javascript 如何使用画布实现阈值效果?

Javascript 如何使用画布实现阈值效果?,javascript,canvas,filter,effect,threshold,Javascript,Canvas,Filter,Effect,Threshold,我发现这本指南展示了使用画布和JavaScript的图像过滤器/效果: 不过,我不知道如何实现它。我不擅长JavaScript(我是一名图形设计师),所以我甚至不理解语法。我从页面中提取了此代码,但我不知道它是否完整或如何使用: Filters = {}; Filters.threshold = function(pixels, threshold) { var d = pixels.data; for (var i=0; i<d.length; i+=4) {

我发现这本指南展示了使用画布和JavaScript的图像过滤器/效果:

不过,我不知道如何实现它。我不擅长JavaScript(我是一名图形设计师),所以我甚至不理解语法。我从页面中提取了此代码,但我不知道它是否完整或如何使用:

Filters = {};

Filters.threshold = function(pixels, threshold) {
    var d = pixels.data;
    for (var i=0; i<d.length; i+=4) {
        var r = d[i];
        var g = d[i+1];
        var b = d[i+2];
        var v = (0.2126*r + 0.7152*g + 0.0722*b >= threshold) ? 255 : 0;
        d[i] = d[i+1] = d[i+2] = v
    }
    return pixels;
};

threshold = function() {
  runFilter('threshold', Filters.threshold, 128);
}
Filters={};
Filters.threshold=函数(像素,阈值){
var d=像素数据;
对于(变量i=0;i=threshold)?255:0;
d[i]=d[i+1]=d[i+2]=v
}
返回像素;
};
阈值=函数(){
runFilter('threshold',Filters.threshold,128);
}

div
(使用CSS
背景图像
属性)、
img
canvas
元素上,只要它能工作就无所谓了。

如果您想在HTML
上应用此过滤器,那么画布解决方案不是最好的

相反,请看简单的案例,或者更复杂的案例

您想要的是一个简单的,只能通过CSS过滤器实现:

#目标{
背景图片:url(https://i.stack.imgur.com/5Md7Z.jpg);
宽度:600px;
高度:600px;
滤镜:亮度(115%)灰度(100%)对比度(5000%);
}

过滤器对图像数据起作用。图像数据无法显示,因此需要转换为某些可显示的形式,如画布

您还需要从图像中获取图像数据。标准图像不允许访问像素,因此需要将图像转换为画布以获取像素

注意不安全的图像(跨域、本地文件存储)可能无法访问像素。如果您在请求中提供了正确的头并且服务器接受了请求,则某些跨域映像将允许访问(如下例所示)

例子 我在Filter对象中添加了一些助手函数,这些函数将从各种类似图像的源中复制、创建和获取像素

示例中的
Filter
提取术语image。在该示例中,图像是类似图像的对象,可以是
CSSImageValue
HTMLImageElement
SVGImageElement
HTMLVideoElement
htmlcanvaseelement
ImageBitmap
offscreencavas
ImageData
中的任意一种

const image=新图像;
image.src=”https://upload.wikimedia.org/wikipedia/commons/1/15/Late_model_Ford_Model_T.jpg";
image.crossOrigin=“匿名”//科尔斯
addEventListener(“load”,()=>applyFilter(image),{once:true});
常数过滤器={
createImage(w,h){
const can=document.createElement(“画布”);
can.width=w;
罐高=h;
还可以;
},
复制图像(img){
const image=this.createImage(img.width,img.height);
const ctx=image.getContext(“2d”);
if(img instanceof ImageData){ctx.putImageData(img,0,0)}
else{ctx.drawImage(img,0,0,img.width,img.height)}
返回图像;
},
获取像素(img){
如果(!(HTMLCanvasElement的img instanceof)){img=this.copyImage(img)}
const ctx=img.getContext(“2d”);
返回ctx.getImageData(0,0,img.width,img.height);
},
阈值(像素,阈值,光=[255255255],暗=[0,0,0]){//RGB的光,暗阵列
var d=像素数,i=0,l=d.长度;
而(l-->0){
常数v=d[i]*0.2126+d[i+1]*0.7152+d[i+2]*0.0722;
[d[i],d[i+1],d[i+2]]=v>=阈值?光:暗;
i+=4;
}
返回像素;
}
};
函数applyFilter(图像){
const pixels=Filters.getPixels(图像);
阈值(像素,100);
const thresholdImage=Filters.copyImage(像素);
att.classList.remove(“hide”);//可以看到图像以便显示属性
document.body.appendChild(image);//将原件添加到页面
document.body.appendChild(thresholdImage);//将筛选后的添加到页面
}
/*图像源
由Rmhermen-从en.wikipedia转移到Commons,抄送By-SA 3.0,https://commons.wikimedia.org/w/index.php?curid=468996 
*/
.hide{display:none}
div{font size:x-small}
画布{宽度:46%}
img{宽度:46%}

由Rmhermen编写-从en.wikipedia转到Commons.CC By-SA 3.0,
这是一个非常聪明的解决方案。它只是简化了整个过程,而没有使用JavaScript。我刚刚实现了这个,它就像一个符咒一样工作,甚至与父元素上的其他嵌套过滤器一起工作。