CanvasRenderingContext2D: drawImage() 方法

Baseline 广泛可用 *

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2015 年 7 月⁩以来,各浏览器均已提供此特性。

* 此特性的某些部分可能存在不同级别的支持。

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

语法

js
drawImage(image, dx, dy)
drawImage(image, dx, dy, dWidth, dHeight)
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)

drawImage

参数

图片

要在此上下文中绘制的元素。规范允许任何画布图像源,具体来说,可以是 HTMLImageElementSVGImageElementHTMLVideoElementHTMLCanvasElementImageBitmapOffscreenCanvasVideoFrame

sx 可选

要绘制到目标上下文的源 image 的子矩形的左上角的 x 轴坐标。使用 3 个或 5 个参数的语法可以省略此参数。

sy 可选

要绘制到目标上下文的源 image 的子矩形的左上角的 y 轴坐标。使用 3 个或 5 个参数的语法可以省略此参数。

sWidth 可选

要绘制到目标上下文的源 image 的子矩形的宽度。如果未指定,则使用从由 sxsy 指定的坐标到图像右下角的所有矩形。使用 3 个或 5 个参数的语法可以省略此参数。负值会在相反方向上扩展子矩形,但像素始终会沿原始方向处理,图像不会翻转。

sHeight 可选

要绘制到目标上下文的源 image 的子矩形的高度。使用 3 个或 5 个参数的语法可以省略此参数。负值会在相反方向上扩展子矩形,但像素始终会沿原始方向处理,图像不会翻转。

dx

在目标画布上放置源 image 左上角的 x 轴坐标。

dy

在目标画布上放置源 image 左上角的 y 轴坐标。

dWidth

在目标画布上绘制 image 的宽度。这允许缩放绘制的图像。如果未指定,则绘制时图像宽度不会缩放。请注意,此参数不包含在 3 个参数的语法中。负值会在相反方向上扩展子矩形,但像素始终会沿原始方向处理,图像不会翻转。

dHeight

在目标画布上绘制 image 的高度。这允许缩放绘制的图像。如果未指定,则绘制时图像高度不会缩放。请注意,此参数不包含在 3 个参数的语法中。负值会在相反方向上扩展子矩形,但像素始终会沿原始方向处理,图像不会翻转。

返回值

无(undefined)。

异常

InvalidStateError DOMException

当图像没有图像数据,或者画布或源矩形的宽度或高度为零时引发。

TypeMismatchError DOMException

当作为参数传递的图像为 nullundefined 时引发。

示例

将图像绘制到画布

此示例使用 drawImage() 方法将图像绘制到画布。

HTML

html
<canvas id="canvas"></canvas>
<div class="hidden">
  <img
    id="source"
    src="https://mdn.github.io/shared-assets/images/examples/rhino.jpg"
    width="300"
    height="227" />
</div>

JavaScript

源图像来自坐标 (33, 71),宽度为 104,高度为 124。它被绘制到画布上的 (21, 20) 位置,并被赋予宽度 87 和高度 104。

js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const image = document.getElementById("source");

image.addEventListener("load", (e) => {
  ctx.drawImage(image, 33, 71, 104, 124, 21, 20, 87, 104);
});

结果

理解源元素大小

drawImage() 方法在绘制时使用源元素的CSS 像素的固有尺寸

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

HTML

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

JavaScript

js
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.github.io/shared-assets/images/examples/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);
}

结果

规范

规范
HTML
# dom-context-2d-drawimage-dev

浏览器兼容性

注意

  • drawImage() 仅在 HTMLVideoElementHTMLMediaElement.readyState 大于 1 时(即,在设置 currentTime 属性后触发了 seek 事件)才能正确工作。
  • drawImage() 在绘制、裁剪和/或缩放时将始终使用源元素的CSS 像素的固有尺寸
  • 在某些旧版本的浏览器中,drawImage() 会忽略图像中的所有 EXIF 元数据,包括方向。这种行为在 iOS 设备上尤其令人头疼。您应该自己检测方向并使用 rotate() 来纠正它。

另见