CanvasRenderingContext2D putImageData奇怪

时间:2018-03-26 22:10:24

标签: javascript canvas

所以我在我们公司的一个项目中添加了一些图像处理功能。部分功能是图像裁剪器,希望在某种程度上“自动检测”裁剪后的图像。如果我们的猜测很糟糕,他们可以拖延删除裁剪点,但大多数图像应该能够自动裁剪。

我的问题是当我将数据放回到画布索引中时根据文档对我的工作似乎没有任何意义。我正在尝试使用我找到的矩形并将画布转换为单个图像大小,现在将包含整个矩形。

    let width = right - left + 1, height = bottom - top + 1;

    canvas.width = width;
    canvas.height = height;

    ctx.putImageData(imageBuffer, -left, -top, left, top, width,height);

这给了我正确的图像。我希望根据文档证明以下代码是正确的。我在mspaint中验证了我的rect索引是正确的所以我知道这不是我的算法得出奇怪的数字。

    let width = right - left + 1, height = bottom - top + 1;

    canvas.width = width;
    canvas.height = height;

    ctx.putImageData(imageBuffer, 0, 0, left, top, width,height);

为什么你必须为第二个&第三个论点?我已经验证了它在Chrome和Chrome中的行为都是这样的Firefox浏览器。

1 个答案:

答案 0 :(得分:0)

是的,它可能有点令人困惑,但当你putImageData时,destinationWidthdestinationHeight,例如drawImage,总是等于ImageData的widthheight

putImageData() dirtyX dirtyY dirtyWidth dirtyHeight 值的最后4个参数相对于ImageData的边界。

因此,对于前两个参数,您只需设置ImageData边界的位置,使用其他4个参数设置像素在此ImageData边界中的位置。

var ctx = canvas.getContext('2d');

var imgBound = {
  x: 10,
  y: 10,
  width: 100,
  height: 100
},
innerImg = {
  x: 20,
  y: 20,
  width: 200,
  height: 200
};
// a new ImageData, the size of our canvas
var img = ctx.createImageData(imgBound.width, imgBound.height);
// fill it with noise
var d = new Uint32Array(img.data.buffer);
for(var i=0;i<d.length; i++)
  d[i] = Math.random() * 0xFFFFFFFF;

function draw() {

ctx.putImageData(img,
  imgBound.x,
  imgBound.y,
  innerImg.x,
  innerImg.y,
  innerImg.width,
  innerImg.height
);
// the ImageData's boundaries
ctx.strokeStyle = 'blue';
ctx.strokeRect(imgBound.x, imgBound.y, imgBound.width, imgBound.height);

// our pixels boundaries relative to the ImageData's bbox
ctx.strokeStyle = 'green';
ctx.strokeRect(
 // for stroke() we need to add the ImageData's translation
  innerImg.x + imgBound.x,
  innerImg.y + imgBound.y,
  innerImg.width,
  innerImg.height
  );
}
var inner_direction = -1,
  imgBound_direction = -1;
function anim() {
  innerImg.width += inner_direction;
  innerImg.height += inner_direction;
  if(innerImg.width <= -50 || innerImg.width > 200) inner_direction *= -1;
  imgBound.x += imgBound_direction;
  if(imgBound.x <= 0 || imgBound.x > 200)
    imgBound_direction *= -1;
  
  ctx.clearRect(0,0,canvas.width,canvas.height);
  draw();
  requestAnimationFrame(anim);
}
anim();
canvas{border: 1px solid;}
<canvas id="canvas" width="300" height="300"></canvas>