Skip to content Skip to sidebar Skip to footer

CanvasRenderingContext2D PutImageData Oddity

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 d

Solution 1:

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.

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

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>

Post a Comment for "CanvasRenderingContext2D PutImageData Oddity"