繁体   English   中英

克服画布上的抗锯齿事件

[英]Overcoming antialiasing on canvas lines for mouse event

我正面临一个显而易见的问题,即HTML画布中的行不能禁用抗锯齿(例如, 此问题提到只能针对使用context.imageSmoothingEnabled= false图像执行此操作,而不能对行进行此操作)。

我想知道是否有任何更新,是否有可能画出清晰(即使“像素化”)的线条? 我所需要的就是例如使用普通的“铅笔”工具(请参见下面的左侧笔划)而不是更平滑的“画笔”类型(请参见右侧笔划)时MS Paint能够实现的功能。

油漆中的清晰像素线

当前,HTML画布中的行看起来更像是“画笔”类型。 画布线条模糊

这是一个问题,因为我试图设置一个鼠标事件以使行的颜色准确无误,但是在实际颜色周围使用了抗锯齿功能后,它会在光标到达中心部分之前返回一些不需要的颜色的线。

有人可以确认真的没有办法在画布上强迫“铅笔”状的笔触吗? 如果是这样,是否可能有一个简单的解决方法,例如“切除”笔触的边缘?

您可以使用SVG滤镜在画布上绘制这样的像素化形状,该滤镜会删除形状边缘的alpha值。 (但是SVG过滤器有点重。)

 const ctx = canvas.getContext("2d"); //normal line(antialiased) ctx.moveTo(20,20); ctx.lineTo(180,20); ctx.stroke(); //set "crisp edge" filter ctx.filter = "url(#crisp)"; //crisp line ctx.beginPath();ctx.moveTo(20,40); ctx.lineTo(180,40); ctx.moveTo(20, 50); ctx.lineTo(180, 70); //crisp circle ctx.moveTo(150, 130); ctx.arc(100, 130, 50, 0, Math.PI*2); ctx.stroke(); 
 <canvas id="canvas" width="200" height="200"></canvas> <svg style="visibility:hidden;width:0;height:0;"> <defs> <!--SVG filter to remove alpha--> <filter id="crisp"> <feComponentTransfer> <feFuncA type="discrete" tableValues="0,1"></feFuncA> </feComponentTransfer> </filter> </defs> </svg> 

注意:但是Chrome通过使用SVG过滤器会在输出图像上引发安全错误。


如果您需要自己实现此类过滤器, ImageData对象将为您提供帮助。 这没有安全错误风险。

但是手工制作的过滤器太重,无法应用于每个事件图纸。 您应该仔细考虑申请时间。

 const ctx = canvas.getContext("2d"); //temporary canvas to removeAlpha const tmp = document.createElement("canvas"); [tmp.width, tmp.height] = [canvas.width, canvas.height]; const tctx = tmp.getContext("2d"); //normal line(antialiased) ctx.moveTo(20,20); ctx.lineTo(180,20); ctx.stroke(); //crisp line tctx.beginPath(); tctx.moveTo(20,40); tctx.lineTo(180,40); tctx.moveTo(20, 50); tctx.lineTo(180, 70); removeAlpha(); //crisp circle tctx.moveTo(150, 130); tctx.arc(100, 130, 50, 0, Math.PI*2); tctx.stroke(); removeAlpha(); //remove alpha on tmp canvas and draw it to main canvas. function removeAlpha(){ const threshold = 128;//you can change the value const id = tctx.getImageData(0, 0, tmp.width, tmp.height); const data = id.data;//pixel data array //remove alpha values pixel by pixel. for(let i = 0, len = canvas.width * canvas.height; i<len; i++){ const apos = i * 4 + 3;//alpha data position const a = data[apos]; data[apos] = a > threshold ? 255 : 0; } tctx.putImageData(id, 0, 0); ctx.drawImage(tmp, 0, 0); tctx.clearRect(0, 0, tmp.width, tmp.height); } 
 <canvas id="canvas" width="200" height="200"></canvas> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM