Cropping images using Canvas

Cropping images using Canvas

overview

In web development, we often need to crop pictures to meet different size requirements or realize partial display of pictures. This blog will give you an in-depth understanding of how to use Canvas technology to realize image cropping. We will use an example to demonstrate how to use Canvas to draw pictures, and perform cropping operations through mask layer and mouse interaction. Let's start this Canvas journey!

project structure

First, let's look at the structure of the project. We will use HTML, CSS and JavaScript to realize the Canvas crop image function, the code is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- 省略部分代码 -->
</head>
<body>
  <!-- 省略部分代码 -->

  <div>
    <input type="file" id="imageFile" accept="image/*" />
  </div>

  <div class="canvas-container">
    <canvas id="can"></canvas>
  </div>

  <div class="canvas2-container">
    <canvas id="can2"></canvas>
  </div>

  <script>
    // JavaScript代码
  </script>

</body>
</html>

We will use three divcontainers, which are used to display the original image, the cropped image, and the cropped area. Among them, <input type="file" id="imageFile" accept="image/*" />it is used to upload pictures.

Initialize Canvas

In the JavaScript part, we first get the Canvas element and its context, as follows:

const oContainer = document.querySelector('.canvas-container');
const oContainer2 = document.querySelector('.canvas2-container');
const oImageFile = document.querySelector('#imageFile');
const oCan = document.getElementById('can');
const oCan2 = document.getElementById('can2');
const ctx = oCan.getContext('2d');
const ctx2 = oCan2.getContext('2d');

We use querySelectorthe method to get the .canvas-containerand .canvas2-containerelement as the image container, #imageFileand the image upload button. Next, we get the two Canvas elements and their context.

Image loading and drawing

Next, we need to listen to the event of the image upload button and draw it on the Canvas after selecting the image:

const init = () => {
  bindEvent();
}

function bindEvent () {
  oImageFile.addEventListener('change', handleFileChange, false);
  // ... 其他事件监听 ...
}

function handleFileChange (e) {
  const file = e.target.files[0];
  const reader = new FileReader();

  reader.readAsDataURL(file);
  reader.onload = function (e) {
    const data = e.target.result;
    oImage.src = data;

    oImage.onload = function () {
      const { width, height } = this;
      generateCanvas(oContainer, oCan, width, height);
      ctx.drawImage(oImage, 0, 0, width, height);
      drawImageMask(0, 0, width, height, MASK_OPACITY);
    }
  }
}

function generateCanvas (container, canvas, width, height) {
  container.style.width = width + 'px';
  container.style.height = height + 'px';
  canvas.width = width;
  canvas.height = height;
  container.style.display = 'block';
}

 

In bindEventthe function, we add changean event listener to the image upload button, and after selecting the image, FileReaderread the image file and draw it on the Canvas. We use drawImagethe method to draw the picture on the Canvas, and call generateCanvasthe function to make the size of the Canvas consistent with the picture. At the same time, we call drawImageMaskthe function to draw the mask for display when cropping.

cropping operation

Next, we need to implement the clipping operation. When the user mouse clicks and drags, we can get the mouse position and then draw the clipping rectangle:

function handleCanvasMouseDown (e) {
  initPos = [ e.offsetX, e.offsetY ];

  oCan.addEventListener('mousemove', handleCanvasMouseMove, false);
  oCan.addEventListener('mouseup', handleCanvasMouseUp, false);
}

function handleCanvasMouseMove (e) {
  const endX = e.offsetX;
  const endY = e.offsetY;
  const [ startX, startY ] = initPos;
  const rectWidth = endX - startX;
  const rectHeight = endY - startY;
  const { width, height } = oCan;

  screenShotData = [ startX, startY, rectWidth, rectHeight ];

  ctx.clearRect(0, 0, width, height);
  drawImageMask(0, 0, width, height, MASK_OPACITY);
  drawScreenShot(width, height, rectWidth, rectHeight);
}

function handleCanvasMouseUp () {
  oCan.removeEventListener('mousemove', handleCanvasMouseMove, false);
  oCan.removeEventListener('mouseup', handleCanvasMouseUp, false);
  drawScreenShotImage(screenShotData);
}

In handleCanvasMouseDownthe function, we record the position of the mouse click. In handleCanvasMouseMovethe function, draw the rectangle of the clipping area according to the position of the mouse movement, and draw a black translucent mask on top of the mask. In handleCanvasMouseUpthe function, when the mouse is released, we draw the cropped image. 

image cropping

Finally, we need to implement the cropping function of the image. Get the data of the clipping area through ctx.getImageDatathe method and draw it on another Canvas:

function drawScreenShot (canWidth, canHeight, rectWidth, rectHeight) {
  ctx.globalCompositeOperation = 'destination-out';
  ctx.fillStyle = '#000';
  ctx.fillRect(...initPos, rectWidth, rectHeight);

  ctx.globalCompositeOperation = 'destination-over';
  ctx.drawImage(oImage, 0, 0, canWidth, canHeight, 0, 0, canWidth, canHeight);
}

function drawScreenShotImage (screenShotData) {
  const data = ctx.getImageData(...screenShotData);
  generateCanvas(oContainer2, oCan2, screenShotData[2], screenShotData[3]);
  ctx2.clearRect(...screenShotData);
  ctx2.putImageData(data, 0, 0);
}

init();

 In drawScreenShotthe function, we use globalCompositeOperationattributes to control the way of drawing, first draw the clipping area and clear it on the mask, and then draw the original image. In drawScreenShotImagethe function, we use ctx.getImageDatathe method to get the data of the clipping area, and then draw it on the second Canvas.

Summarize

Through the above steps, we have successfully implemented the function of using Canvas to crop images. By listening to the mouse event, we can draw the cropping area on the picture, and finally realize the cropping effect of the picture. Canvas technology is an indispensable part of Web front-end development. I hope this blog can help you better understand the application scenarios and practical skills of Canvas. Thanks for reading! 

 

 Learning from station B up - front-end Ono Sensen

Guess you like

Origin blog.csdn.net/weixin_60895836/article/details/132092973