You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Canvas平移旋转后使用getImageData提取指定图像区域的问题

问题

我尝试用Canvas的getImageData提取图像中旋转后的矩形区域,但translate和rotate这类变换对getImageData完全无效,没法正确拿到目标区域的数据。目标区域是图中黑色边框的旋转矩形:

旋转的矩形区域

当前代码如下:

JavaScript

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

var img = new Image();
img.onload = function() {
  ctx.drawImage(img, 0, 0, img.width, img.height);
  drawRect();
}
img.src = "https://dummyimage.com/300x150/5873f0/ffffff.jpg";


function drawRect() {
  ctx.save();
  ctx.translate(75, 100);
  ctx.rotate(20 * Math.PI / 180)
  // 这行无法获取正确的旋转区域数据
  // imgData = ctx.getImageData(-50, -25, 100, 50);
  ctx.strokeStyle = 'black';
  ctx.strokeRect(-50, -25, 100, 50);
  ctx.restore()
}

HTML

<canvas id="myCanvas" width="300" height="150">
Your browser does not support the HTML5 canvas tag.
</canvas>

解决方法

getImageData是基于画布原始坐标系统的,完全不受translate、rotate等变换影响,所以直接调用拿不到旋转区域。可以用临时画布绕开这个限制,具体步骤如下:

核心思路

  1. 创建一个和目标矩形尺寸相同的临时画布;
  2. 在临时画布上反向旋转,把原图像的旋转区域“转正”后绘制进去;
  3. 直接从临时画布提取图像数据。

修改后的完整代码

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

var img = new Image();
img.crossOrigin = "anonymous"; // 处理跨域图片操作限制
img.onload = function() {
  ctx.drawImage(img, 0, 0, img.width, img.height);
  drawRect();
  // 提取旋转区域的图像数据
  const rotatedData = getRotatedRegion(img, 75, 100, 20, 100, 50);
  // 将提取的数据绘制到画布右上角,验证结果
  ctx.putImageData(rotatedData, c.width - rotatedData.width - 10, 10);
}
img.src = "https://dummyimage.com/300x150/5873f0/ffffff.jpg";

function drawRect() {
  ctx.save();
  ctx.translate(75, 100);
  ctx.rotate(20 * Math.PI / 180)
  ctx.strokeStyle = 'black';
  ctx.strokeRect(-50, -25, 100, 50);
  ctx.restore()
}

// 提取指定旋转区域的图像数据
function getRotatedRegion(image, centerX, centerY, angleDeg, rectWidth, rectHeight) {
  const tempCanvas = document.createElement('canvas');
  tempCanvas.width = rectWidth;
  tempCanvas.height = rectHeight;
  const tempCtx = tempCanvas.getContext('2d');
  const angleRad = angleDeg * Math.PI / 180;

  // 临时画布变换:先移到中心,反向旋转,再定位到原图像的旋转中心
  tempCtx.save();
  tempCtx.translate(rectWidth/2, rectHeight/2);
  tempCtx.rotate(-angleRad); // 反向旋转,让原图像的旋转区域转正
  tempCtx.translate(-centerX, -centerY);
  // 绘制原图像,覆盖临时画布
  tempCtx.drawImage(image, 0, 0);
  tempCtx.restore();

  // 提取临时画布的图像数据
  return tempCtx.getImageData(0, 0, rectWidth, rectHeight);
}

说明

  • getRotatedRegion函数是核心:通过临时画布的反向旋转,把原图像中旋转的区域转正后绘制,这样getImageData就能拿到正确的矩形数据;
  • 添加img.crossOrigin = "anonymous"是为了解决跨域图片无法进行像素操作的问题;
  • 最后把提取的数据绘制到原画布右上角,方便直观验证结果是否正确。

内容的提问来源于stack exchange,提问作者Matthieu Planté

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 06:25:21