CanvasRenderingContext2D putImageData奇数 [英] CanvasRenderingContext2D putImageData oddity

查看:70
本文介绍了CanvasRenderingContext2D putImageData奇数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我要为我们的一个公司项目添加一些图像处理功能。该功能的一部分是图像裁剪器,它希望在某种程度上自动检测裁剪后的图像。如果我们的猜测很糟糕,他们可以拖动&

So i'm adding some image manipulation functions to one of our company projects. Part of the feature is an image cropper with the desire to 'auto-detect' the cropped image to some degree. If our guess is bad they can just drag & drop the cropper points, but most images people should be able to be auto-cropped.

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

My issue is when i'm putting the data back into the canvas indexes that work don't seem make any sense to me based on the documentation. I'm trying to take the rect I find and convert he canvas to a single image size that will now contain my whole rect.

    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索引正确,所以我知道不是我的算法提出了奇怪的数字。

This gives me the correct image. I would have expected based on the documentation that the below code would be correct. I verified in mspaint that my indexes for the rect are correct so I know it isn't my algorithm coming up with weird numbers.

    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& Firefox。

Why do you have to put a negative indexing for the 2nd & 3rd argument? I've verified it behaves like this in both Chrome & Firefox.

推荐答案

是的,可能有些令人困惑,但是当您 putImageData destinationWidth destinationHeight ,例如,在 drawImage 始终等于ImageData的宽度高度

Yes, it might be a bit confusing, but when you putImageData, the destinationWidth and destinationHeight you would have in e.g drawImage, are always equal to the ImageData's width and height.

putImageData() dirtyX dirtyY dirtyWidth dirtyHeight 值是相对于ImageData的边界的。

The 4 last params of putImageData(), dirtyX, dirtyY, dirtyWidth and dirtyHeight values are relative to the ImageData's boundaries.

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

So with the first two params, you just set the position of the ImageData's boundaries, with the 4 others, you set the position of your pixels in this ImageData's boundary.

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>

这篇关于CanvasRenderingContext2D putImageData奇数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆