我有一块画布,可以使用fabric.js绘制一些形状。然后,我填充这些形状,并使用context.drawImage()将它们绘制在另一个画布上,并使用canvas.toDataURL()导出为png。
我已经关闭了我绘制到的画布以及导出到png的画布的enableRetinaScaling和imageSmoothingEnabled。
我得到的png在形状的边缘具有不同的颜色像素,并且似乎抗锯齿或模糊。有没有一种方法可以禁用此功能,并让每个像素的边框周围都具有相同的颜色?我知道这将导致边缘不光滑,这很好。
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>
答案 0 :(得分:0)
这似乎是由用于在画布上绘制线条的算法引起的,我认为我们没有办法更改它,唯一的选择是使用其他算法自己绘制所有内容,例如:
https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
在您的示例中,您正在使用fabric.js,但是这种情况也以最基本的线条绘制形式发生,这是and示例:
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>
答案 1 :(得分:0)
这是一个可能的解决方案。 您不能从画布上删除别名,至少不在规范中,并且不受您的控制。
但是您可以在导出像素后对其进行操作。
输出是:
但不适用于重叠的形状。
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>