CanvasRenderingContext2D.drawImage()

Canvas 2D API 中的 CanvasRenderingContext2D.drawImage() 方法提供了多种方式在Canvas上绘制图像。

语法

void ctx.drawImage(image, dx, dy);
void ctx.drawImage(image, dx, dy, dWidth, dHeight);
void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

drawImage

参数

image
绘制到上下文的元素。允许任何的 canvas 图像源(CanvasImageSource),例如:CSSImageValueHTMLImageElementSVGImageElementHTMLVideoElementHTMLCanvasElementImageBitmap 或者OffscreenCanvas
sx可选
需要绘制到目标上下文中的,image的矩形(裁剪)选择框的左上角 X 轴坐标。
sy可选
需要绘制到目标上下文中的,image的矩形(裁剪)选择框的左上角 Y 轴坐标。
sWidth可选
需要绘制到目标上下文中的,image的矩形(裁剪)选择框的宽度。如果不说明,整个矩形(裁剪)从坐标的sxsy开始,到image的右下角结束。
sHeight可选
需要绘制到目标上下文中的,image的矩形(裁剪)选择框的高度。
dx
image的左上角在目标canvas上 X 轴坐标。
dy
image的左上角在目标canvas上 Y 轴坐标。
dWidth可选
image在目标canvas上绘制的宽度。 允许对绘制的image进行缩放。 如果不说明, 在绘制时image宽度不会缩放。
dHeight可选
image在目标canvas上绘制的高度。 允许对绘制的image进行缩放。 如果不说明, 在绘制时image高度不会缩放。

抛出异常

INDEX_SIZE_ERR
如果 canvas 或者图像矩形区域的宽度或高度为0 。
INVALID_STATE_ERR
图像没有数据。
TYPE_MISMATCH_ERR
提供的原始元素不支持。
NS_ERROR_NOT_AVAILABLE
图像尚未加载。使用.complete === true.onload确定何时准备就绪。

示例

使用 drawImage 方法

这是一段使用 drawImage 方法的简单的代码片段。

HTML

<canvas id="canvas"></canvas>
<div style="display:none;">
  <img id="source" src="https://mdn.mozillademos.org/files/5397/rhino.jpg"
       width="300" height="227">
</div>

JavaScript

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

ctx.drawImage(image, 33, 71, 104, 124, 21, 20, 87, 104);

结果

Playable code
<canvas id="canvas" width="400" height="200" class="playable-canvas"></canvas>
<div style="display:none;">
  <img id="source" src="https://mdn.mozillademos.org/files/5397/rhino.jpg" width="300" height="227">
</div>
<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.drawImage(image, 33, 71, 104, 124, 21, 20, 87, 104);</textarea>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var image = document.getElementById('source');
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);

理解源元素大小

drawImage()方法在绘制时使用源元素的CSS大小。

例如,如果加载图像并在其构造函数中指定可选的大小参数,则必须使用所创建实例的naturalWidthnaturalHeight属性来正确计算裁剪和缩放区域等内容,而不是element.widthelement.height。如果元素是<video> 元素,则videoWidthvideoHeight也是如此,依此类推。

HTML

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

JavaScript

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

const image = new Image(60, 45); // Using optional size for image
image.onload = drawImageActualSize; // Draw when image has loaded

// Load an image of intrinsic size 300x227 in CSS pixels
image.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';

function drawImageActualSize() {
  // Use the intrinsic size of image in CSS pixels for the canvas element
  canvas.width = this.naturalWidth;
  canvas.height = this.naturalHeight;

  // Will draw the image as 300x227, ignoring the custom size of 60x45
  // given in the constructor
  ctx.drawImage(this, 0, 0);

  // To use the custom size we'll have to specify the scale parameters 
  // using the element's width and height properties - lets draw one 
  // on top in the corner:
  ctx.drawImage(this, 0, 0, this.width, this.height);
}

Result

规范说明

Specification Status Comment
HTML Living Standard
CanvasRenderingContext2D.drawImage
Living Standard  

浏览器兼容性

Update compatibility data on GitHub
DesktopMobile
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung Internet
drawImageChrome Full support YesEdge Full support 12Firefox Full support 1.5IE Full support YesOpera Full support YesSafari Full support YesWebView Android Full support YesChrome Android Full support YesFirefox Android Full support 4Opera Android Full support YesSafari iOS Full support YesSamsung Internet Android Full support Yes
ImageBitmap as source imageChrome Full support YesEdge No support NoFirefox Full support 42IE ? Opera ? Safari ? WebView Android Full support YesChrome Android Full support YesFirefox Android Full support 42Opera Android ? Safari iOS ? Samsung Internet Android Full support Yes
Smoothing when downscalingChrome Full support YesEdge ? Firefox Full support 56
Notes
Full support 56
Notes
Notes See bug 1360415 for details.
IE ? Opera Full support YesSafari ? WebView Android Full support YesChrome Android Full support YesFirefox Android Full support 56
Notes
Full support 56
Notes
Notes See bug 1360415 for details.
Opera Android Full support YesSafari iOS ? Samsung Internet Android Full support Yes
SVGImageElement as source imageChrome Full support 59Edge ? Firefox Full support 56IE ? Opera ? Safari ? WebView Android Full support 59Chrome Android Full support 59Firefox Android Full support 56Opera Android ? Safari iOS ? Samsung Internet Android Full support 7.0

Legend

Full support  
Full support
No support  
No support
Compatibility unknown  
Compatibility unknown
See implementation notes.
See implementation notes.

兼容性注解

  • 在 Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2)中,支持通过给 sw 和 sh 赋负值,对图像进行翻转。
  • 从 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2) 开始,drawImage() 按照规范处理负参数,沿着合适的轴翻转矩形。
  • 从(Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2)开始,当drawImage()调用 null 或者 undefined 图像时,会抛出 TYPE_MISMATCH_ERR 异常。
  • 在 Gecko 7.0 (Firefox 7.0 / Thunderbird 7.0 / SeaMonkey 2.4)之前, 如果坐标值是非规定值或者是0,Firefox 会抛出一个异常。 按照规范描述,这种情况不会再发生。
  • Gecko 9.0 (Firefox 9.0 / Thunderbird 9.0 / SeaMonkey 2.6)现在完全支持 CORS 跨域绘制图像,不需要污染的 canvas.
  • Gecko 11.0 (Firefox 11.0 / Thunderbird 11.0 / SeaMonkey 2.8) 现在允许 SVG 作为图像被绘制到 canvas ,不需要 污染的 canvas.

参见