Home > Mobile >  Copy a rectangle from a html canvas that is at an arbitary angle
Copy a rectangle from a html canvas that is at an arbitary angle

Time:12-20

I have a canvas in HTML with an image, and a rectangle defined on the canvas by its four corners. I want to copy the image from the canvas into a new canvas. The difficulty comes that the rectangle will be at an arbitrary angle and so I cant simply use 'getImageData' as I had previously planned.

I basically need to write a function which takes a canvas and the four points and returns a canvas as illustrated in this image. I welcome any suggestions as to the best way to start.

Image showing the process of copying a section of one canvas to a new image

CodePudding user response:

You could use openCV and warpAffine. I think there are web implementations of openCV these days (https://docs.opencv.org/3.4/df/d0a/tutorial_js_intro.html). There may be another simpler library for this. You're likely going to need and understanding of matrix transforms (https://en.wikipedia.org/wiki/Transformation_matrix).

CodePudding user response:

Create a second canvas, apply a rotation transform, and draw your original image onto it.

In the demo below, the first canvas is your source image, and the second is your copied rectangle.

// Create a demo canvas
const canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 150;
document.body.appendChild(canvas);

// Draw an image on the demo canvas
const ctx = canvas.getContext('2d');
const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
gradient.addColorStop(.4, 'cyan');
gradient.addColorStop(.4, 'yellow');
gradient.addColorStop(.6, 'blue');
gradient.addColorStop(.6, 'purple');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);

getRect(canvas, canvas.width / 2, canvas.height / 2, 100, 50, -35 * Math.PI / 180);

function getRect(src, x, y, w, h, angle) {
  // Create a canvas for the rectangle's data
  const _canvas = document.createElement('canvas');
  _canvas.width = w;
  _canvas.height = h;
  document.body.appendChild(_canvas);
  const _ctx = _canvas.getContext('2d');
  _ctx.translate(w / 2, h / 2);
  _ctx.rotate(-angle);
  _ctx.drawImage(src, -src.width / 2, -src.height / 2);
  
  // getImageData here from _canvas, if desired
  
  // Show an outline around the source rectangle
  ctx.translate(x, y);
  ctx.rotate(angle);
  ctx.strokeStyle = 'red';
  ctx.strokeRect(-w / 2, -h / 2, w, h);
}
canvas {
  margin-right: 20px;
}

  • Related