MDN wants to learn about developers like you: https://qsurvey.mozilla.com/s3/MDN-dev-survey

CanvasRenderingContext2D.putImageData()

CanvasRenderingContext2D.putImageData() 是 Canvas 2D API 将数据从已有的 ImageData 对象绘制到位图的方法。 如果提供了脏矩形,只能绘制矩形的像素。 

语法

void ctx.putImageData(imagedata, dx, dy);
void ctx.putImageData(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);

参数

imageData

     ImageData ,包含像素值的数组对象。

dx
源图像数据在目标画布中的位置偏移量(x 轴方向的偏移量)。
dy
源图像数据在目标画布中的位置偏移量(y 轴方向的偏移量)。
dirtyX 可选
在源图像数据中,矩形区域左上角的位置。默认是整个图像数据的左上角(x 坐标)。
dirtyY 可选
在源图像数据中,矩形区域左上角的位置。默认是整个图像数据的左上角(y 坐标)。
dirtyWidth 可选
在源图像数据中,矩形区域的宽度。默认是图像数据的宽度。
dirtyHeight 可选
在源图像数据中,矩形区域的高度。默认是图像数据的高度。

抛出错误

NotSupportedError
如果任何一个变量被设置成无穷大,则会抛出此错误。
InvalidStateError
如果过图像数据对象的数据被分离,会抛出此错误。

示例

理解putImageData

通过CanvasRenderingContext2D.fillRect()方法实现,更好地理解putImageData的执行算法. 获取更多信息,参见 使用Canvas控制像素 和 ImageData 对象。

HTML

<canvas id="canvas"></canvas>

JavaScript

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

function putImageData(ctx, imageData, dx, dy,
    dirtyX, dirtyY, dirtyWidth, dirtyHeight) {
  var data = imageData.data;
  var height = imageData.height;
  var width = imageData.width;
  dirtyX = dirtyX || 0;
  dirtyY = dirtyY || 0;
  dirtyWidth = dirtyWidth !== undefined? dirtyWidth: width;
  dirtyHeight = dirtyHeight !== undefined? dirtyHeight: height;
  var limitBottom = dirtyY + dirtyHeight;
  var limitRight = dirtyX + dirtyWidth;
  for (var y = dirtyY; y < limitBottom; y++) {
    for (var x = dirtyX; x < limitRight; x++) {
      var pos = y * width + x;
      ctx.fillStyle = 'rgba(' + data[pos*4+0]
                        + ',' + data[pos*4+1]
                        + ',' + data[pos*4+2]
                        + ',' + (data[pos*4+3]/255) + ')';
      ctx.fillRect(x + dx, y + dy, 1, 1);
    }
  }
}

// Draw content onto the canvas
ctx.fillRect(0,0,100,100);
// Create an ImageData object from it
var imagedata = ctx.getImageData(0,0,100,100);
// use the putImageData function that illustrates how putImageData works
putImageData(ctx, imagedata, 150, 0, 50, 50, 25, 25);

修改下面的代码并在线查看 canvas 的变化:

Playable code
<canvas id="canvas" width="400" height="200" class="playable-canvas"></canvas>
<div class="playable-buttons">
  <input id="edit" type="button" value="Edit" />
  <input id="reset" type="button" value="Reset" />
</div>
<textarea id="code" class="playable-code">
ctx.fillRect(0,0,100,100);
var imagedata = ctx.getImageData(0,0,100,100);
putImageData(ctx, imagedata, 150, 0, 50, 50, 25, 25);</textarea>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var textarea = document.getElementById("code");
var reset = document.getElementById("reset");
var edit = document.getElementById("edit");
var code = textarea.value;

function drawCanvas() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  eval(textarea.value);
}

reset.addEventListener("click", function() {
  textarea.value = code;
  drawCanvas();
});

edit.addEventListener("click", function() {
  textarea.focus();
})

textarea.addEventListener("input", drawCanvas);
window.addEventListener("load", drawCanvas);

function putImageData(ctx, imageData, dx, dy,
    dirtyX, dirtyY, dirtyWidth, dirtyHeight) {
  var data = imageData.data;
  var height = imageData.height;
  var width = imageData.width;
  dirtyX = dirtyX || 0;
  dirtyY = dirtyY || 0;
  dirtyWidth = dirtyWidth !== undefined? dirtyWidth: width;
  dirtyHeight = dirtyHeight !== undefined? dirtyHeight: height;
  var limitBottom = dirtyY + dirtyHeight;
  var limitRight = dirtyX + dirtyWidth;
  for (var y = dirtyY; y < limitBottom; y++) {
    for (var x = dirtyX; x < limitRight; x++) {
      var pos = y * width + x;
      ctx.fillStyle = 'rgba(' + data[pos*4+0]
                        + ',' + data[pos*4+1]
                        + ',' + data[pos*4+2]
                        + ',' + (data[pos*4+3]/255) + ')';
      ctx.fillRect(x + dx, y + dy, 1, 1);
    }
  }
}

规范描述

Specification Status Comment
WHATWG HTML Living Standard
CanvasRenderingContext2D.putImageData
Living Standard  

浏览器兼容性

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support (Yes) (Yes) (Yes) (Yes) (Yes)
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support (Yes) (Yes) (Yes) (Yes) (Yes) (Yes)

兼容性注解

  • 从 Gecko 10.0 (Firefox 10.0 / Thunderbird 10.0 / SeaMonkey 2.7)开始,给任何参数设置非限定性的值并调用 putImageData() 将会被忽略,而不是抛出异常。
  • 为了遵循说明,从 Gecko 16.0 (Firefox 16.0 / Thunderbird 16.0 / SeaMonkey 2.13)开始,使用无效的变量数量调用该方法(只有3个或7个数的变量是有效的), 将会抛出一个错误 (bug 762657)。

参见

文档标签和贡献者

 此页面的贡献者: teoli, ice-i-snow
 最后编辑者: teoli,