Html canvas 元素的 getImageData 与 Fabricjs canvas 的内容不匹配



我在(80,80(处添加了一个结构Rect,然后在该位置调用getImageData。然而,我从那个位置得到的数据与我放在那里的Rect不匹配。相反,我发现数据在(60,60(左右。

var canvas = new fabric.Canvas('fabric-canvas');
canvas.setHeight(800);
canvas.setWidth(800);
var rect = new fabric.Rect({
left: 80,
top: 80,
fill: 'red',
width: 20,
height: 20
});
canvas.add(rect);
// This doesn't work
let data = canvas.getContext('2d').getImageData(80, 80, 20, 20);
canvas.getContext('2d').putImageData(data, 0, 0);
// This "works"
data = canvas.getContext('2d').getImageData(60, 60, 20, 20);
canvas.getContext('2d').putImageData(data, 100, 0);

以下是小提琴演示:https://jsfiddle.net/2wxdb8ua/13/

这怎么可能呢?

问题肯定是由某些缩放引起的,可能是因为您的显示器是高分辨率显示器(也称为视网膜(,也可能是因为页面上应用了浏览器/OS缩放。

您可以自己计算world_coord * window.devicePixelRatio:

var canvas = new fabric.Canvas('fabric-canvas');
canvas.setHeight(800);
canvas.setWidth(800);
var rect = new fabric.Rect({
left: 80,
top: 80,
fill: 'red',
width: 20,
height: 20
});
canvas.add(rect);
let ctx = canvas.getContext('2d').getImageData(...[80, 80, 20, 20].map(fixCoords));
canvas.getContext('2d').putImageData(ctx, ...[0, 0].map(fixCoords));
function fixCoords( coord ) {
return coord * window.devicePixelRatio;
}
canvas#fabric-canvas {
background: white;
border: 2px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.1/fabric.min.js"></script>
<canvas id='fabric-canvas'></canvas>

或者使用initOptionObject:的enableRetinaScaling参数禁用结构的自动缩放

var canvas = new fabric.Canvas('fabric-canvas', {
enableRetinaScaling: false
});
canvas.setHeight(800);
canvas.setWidth(800);
var rect = new fabric.Rect({
left: 80,
top: 80,
fill: 'red',
width: 20,
height: 20
});
canvas.add(rect);
let ctx = canvas.getContext('2d').getImageData(80, 80, 20, 20);
canvas.getContext('2d').putImageData(ctx, 0, 0);
canvas#fabric-canvas {
background: white;
border: 2px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.1/fabric.min.js"></script>
<canvas id='fabric-canvas'></canvas>

但请注意,使用后一种解决方案,您的画布在高分辨率显示器上肯定会变得模糊。

最新更新