Skip to main content

Canvas 裁剪图像 — 使用 JavaScript 裁剪并提取图像区域

拖动蓝色裁剪矩形以选择所需区域,使用控制点调整大小,然后单击按钮提取该区域。

说明: 拖动以移动裁剪框。使用角上的控制点调整大小。单击“裁剪图像”以提取。

import Konva from 'konva';

var width = window.innerWidth;
var height = window.innerHeight;

var stage = new Konva.Stage({
  container: 'container',
  width: width,
  height: height,
});

var layer = new Konva.Layer();
stage.add(layer);

var container = document.getElementById('container');

var controls = document.createElement('div');
controls.style.cssText = 'margin-bottom: 8px; display: flex; gap: 10px; align-items: center; font-family: Arial, sans-serif;';

var cropBtn = document.createElement('button');
cropBtn.textContent = '裁剪图像';
cropBtn.style.cssText = 'padding: 8px 16px; font-size: 14px; background: #0088ff; color: white; border: none; border-radius: 4px; cursor: pointer;';
controls.appendChild(cropBtn);

var resultContainer = document.createElement('div');
resultContainer.style.cssText = 'margin-bottom: 8px;';

container.parentNode.insertBefore(controls, container);
container.parentNode.insertBefore(resultContainer, container);

var imageObj = new Image();
imageObj.onload = function() {
  var bgImage = new Konva.Image({
    image: imageObj,
    width: width,
    height: height,
  });
  layer.add(bgImage);

  var cropRect = new Konva.Rect({
    x: width * 0.15,
    y: height * 0.15,
    width: width * 0.35,
    height: height * 0.4,
    fill: 'rgba(0, 150, 255, 0.15)',
    stroke: '#0088ff',
    strokeWidth: 2,
    dash: [6, 3],
    draggable: true,
  });
  layer.add(cropRect);

  var tr = new Konva.Transformer({
    nodes: [cropRect],
    enabledAnchors: ['top-left', 'top-right', 'bottom-left', 'bottom-right'],
    boundBoxFunc: function(oldBox, newBox) {
      if (newBox.width < 20 || newBox.height < 20) return oldBox;
      return newBox;
    },
  });
  layer.add(tr);
  layer.draw();

  cropBtn.onclick = function() {
    var dataUrl = stage.toDataURL({
      x: cropRect.x(),
      y: cropRect.y(),
      width: cropRect.width() * cropRect.scaleX(),
      height: cropRect.height() * cropRect.scaleY(),
    });
    resultContainer.innerHTML = '';
    var label = document.createElement('p');
    label.textContent = '裁剪结果:';
    label.style.cssText = 'margin: 0 0 4px 0; font-size: 13px; color: #666;';
    resultContainer.appendChild(label);
    var img = document.createElement('img');
    img.src = dataUrl;
    img.style.cssText = 'max-width: 100%; border: 1px solid #ddd; border-radius: 4px;';
    resultContainer.appendChild(img);
  };
};
imageObj.src = 'https://konvajs.org/assets/landscape.jpg';