简体   繁体   English

使用canvas.toDataURL()导出png时禁用抗锯齿

[英]Disable anti-aliasing when exporting a png with canvas.toDataURL()

I have a canvas that I draw some shapes on using fabric.js. 我有一块画布,可以使用fabric.js绘制一些形状。 I then fill those shapes, and draw them on another canvas using context.drawImage() to export to a png using canvas.toDataURL(). 然后,我填充这些形状,并使用context.drawImage()将它们绘制在另一个画布上,以使用canvas.toDataURL()导出为png。

I have turned off enableRetinaScaling and imageSmoothingEnabled for both the canvas I draw onto, and the canvas I export to a png. 我已经关闭了我绘制到的画布以及导出到png的画布的enableRetinaScaling和imageSmoothingEnabled。

My resulting png has different color pixels on the edge of shapes, and seems to be anti-aliased or blurred. 我得到的png在形状的边缘具有不同的颜色像素,并且似乎抗锯齿或模糊。 Is there a way to disable this and have every pixel be the same color around the borders? 有没有一种方法可以禁用此功能,并让每个像素的边框周围都具有相同的颜色? I know this will result is a less smooth edge, and that's fine. 我知道这将导致边缘不那么平滑,这很好。

 const canvas = document.getElementById('canvas'); let ctx = canvas.getContext('2d'); ctx.imageSmoothingEnabled = false; const drawingCanvas = new fabric.Canvas(canvas, { width: 150, height: 150, backgroundColor: 'transparent', selection: false, enableRetinaScaling: false, imageSmoothingEnabled: false, }); let polygon = new fabric.Polygon([ { x: 50, y: 100 }, { x: 70, y: 10 }, { x: 90, y: 100 }, ], { stroke: 'green', fill: 'green', selectable: false, perPixelTargetFind: true, hoverCursor: 'cursor' }); drawingCanvas.add(polygon); drawingCanvas.renderAll(); link = document.getElementById('download'); link.setAttribute("href", canvas.toDataURL()); link.setAttribute("download", "example.png"); 
 <body> <a id="download"><button>Download</button></a> <canvas id="canvas" style="border: solid red 1px" /> </body> <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.5/fabric.js"></script> 

A close up of the png, showing different pixel shades png的特写,显示不同的像素阴影 png的特写,显示不同的像素阴影

This seems to be caused by the algorithm used to draw lines in a canvas, and I don't think we have a way to change it, the only option is to draw everything yourself using a different algorithm like: 这似乎是由用于在画布上绘制线条的算法引起的,我认为我们没有办法更改它,唯一的选择是使用其他算法自己绘制所有内容,例如:
https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

And in your sample you are using fabric.js but this is happening also with the most basic form of line drawing as well, here is and example: 在您的示例中,您正在使用fabric.js,但是这种情况也以最基本的线条绘制形式发生,这是示例:

 const canvas = document.getElementById('canvas'); canvas.width = canvas.height = 50; let ctx = canvas.getContext('2d'); ctx.imageSmoothingEnabled = false ctx.mozImageSmoothingEnabled = false; ctx.translate(0.5, 0.5) ctx.beginPath(); ctx.moveTo(0, 10); ctx.lineTo(10, 10); ctx.lineTo(30, 30); ctx.lineTo(40, 10); ctx.stroke(); ctx.closePath(); link = document.getElementById('download'); link.setAttribute("href", canvas.toDataURL()); link.setAttribute("download", "example.png"); 
 <body> <a id="download"><button>Download</button></a><br> <canvas id="canvas" style="border: solid red 1px" /> </body> 

This is a possible solution. 这是一个可能的解决方案。 You can't remove the aliasing from canvas, at least is not in the specs, and is not under your control. 您不能从画布上删除别名,至少不在规范中,并且不受您的控制。

But you can manipulate pixels after exporting them. 但是您可以在导出像素后对其进行操作。

The ouput is: 输出是:

在此处输入图片说明

But it won't work for overlapping shapes. 但它不适用于重叠的形状。

 const canvas = document.getElementById('canvas'); let ctx = canvas.getContext('2d'); ctx.imageSmoothingEnabled = false; const drawingCanvas = new fabric.Canvas(canvas, { width: 150, height: 150, backgroundColor: 'transparent', selection: false, enableRetinaScaling: false, imageSmoothingEnabled: false, }); let polygon = new fabric.Polygon([ { x: 50, y: 100 }, { x: 70, y: 10 }, { x: 90, y: 100 }, ], { stroke: 'green', fill: 'green', selectable: false, perPixelTargetFind: true, hoverCursor: 'cursor' }); drawingCanvas.add(polygon); drawingCanvas.renderAll(); function myNewImage() { const _canvas = document.createElement('canvas'); const pixels = drawingCanvas.lowerCanvasEl; _canvas.width = pixels.width; _canvas.height = pixels.height; const ctx = _canvas.getContext('2d'); ctx.drawImage(pixels, 0, 0); const data = ctx.getImageData(0, 0, _canvas.width, _canvas.height); const pixelArray = data.data; for (let i = 3; i < pixelArray.length; i += 4) { if (pixelArray[i] < 128) { pixelArray[i] = 0; } else { pixelArray[i] = 255; } } ctx.putImageData(data, 0, 0); return _canvas.toDataURL('image/png'); } link = document.getElementById('download'); link.setAttribute("href", myNewImage()); link.setAttribute("download", "example.png"); 
 <body> <a id="download"><button>Download</button></a> <canvas id="canvas" style="border: solid red 1px" /> </body> <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.5/fabric.js"></script> 

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

相关问题 在IE9中将图像绘制到画布元素时禁用抗锯齿 - Disable anti-aliasing when drawing an image to a canvas-element in IE9 Canvas.toDataUrl(“ image / png”)无法正常工作 - Canvas.toDataUrl(“image/png”) is not working properly JavaScript中“ canvas.toDataURL(” image / png“);”的替代形式? - Alternatives to “canvas.toDataURL(”image/png“);” in JavaScript? 如何在没有抗锯齿的情况下调整画布大小? - How to resize a canvas without anti-aliasing? HTML5 <canvas> 没有抗锯齿 - HTML5 <canvas> without anti-aliasing 从没有消除锯齿的svg创建静态png,有或没有画布 - Create static png from svg without Anti-aliasing, with or without canvas 创建快照时,Chrome 版本 87 不支持 HTML2CANVAS 的 function canvas.toDataURL("image/png") - Chrome version 87 not supporting function canvas.toDataURL("image/png") of HTML2CANVAS when creating snapshot 执行canvas.toDataUrl()时为空白图像 - Blank image when executing canvas.toDataUrl() 在使用canvas.toDataURL(“image / png”)时,仅在Safari中使用SECURITY_ERR:DOM异常18 - SECURITY_ERR: DOM Exception 18 ONLY IN Safari when using canvas.toDataURL(“image/png”) 使用toDataURL()从Canvas导出时如何压缩.png图像? - How to compress .png images when exporting from Canvas using toDataURL()?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM