[英]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的特写,显示不同的像素阴影
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.