The CanvasRenderingContext2D.drawImage() method of the Canvas 2D API provides different ways to draw an image onto the canvas.

Syntax

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

Parameters

image
An element to draw into the context. The specification permits any canvas image source (CanvasImageSource), specifically, a CSSImageValue, an HTMLImageElement, an SVGImageElement, an HTMLVideoElement, an HTMLCanvasElement, an ImageBitmap, or an OffscreenCanvas.
sx Optional
The X coordinate of the top left corner of the sub-rectangle of the source image to draw into the destination context.
syOptional
The Y coordinate of the top left corner of the sub-rectangle of the source image to draw into the destination context.
sWidthOptional
The width of the sub-rectangle of the source image to draw into the destination context. If not specified, the entire rectangle from the coordinates specified by sx and sy to the bottom-right corner of the image is used.
sHeightOptional
The height of the sub-rectangle of the source image to draw into the destination context.
dx
The X coordinate in the destination canvas at which to place the top-left corner of the source image.
dy
The Y coordinate in the destination canvas at which to place the top-left corner of the source image.
dWidthOptional
The width to draw the image in the destination canvas. This allows scaling of the drawn image. If not specified, the image is not scaled in width when drawn.
dHeightOptional
The height to draw the image in the destination canvas. This allows scaling of the drawn image. If not specified, the image is not scaled in height when drawn.
 

Exceptions thrown

INDEX_SIZE_ERR
If the canvas or source rectangle width or height is zero.
INVALID_STATE_ERR
The image has no image data.
TYPE_MISMATCH_ERR
The specified source element isn't supported.
NS_ERROR_NOT_AVAILABLE
The image is not loaded yet. Use .complete === true and .onload to know when it is.

 

Examples

Using the drawImage method

This is just a simple code snippet which uses the drawImage method.

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);

Edit the code below and see your changes update live in the canvas:

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);

Understanding source element size

The drawImage() method uses the source element's intrinsic size in CSS pixels when drawing.

For example, if an image was loaded using the optional size parameters in the constructor you will have to use the naturalWidth and naturalHeight properties of its instance (or videoWidth and videoHeight if the element is a <video> element, etc.) to properly calculate things like crop and scale regions, rather than element.width and element.height.

HTML

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

JavaScript

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

var 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

 

Specifications

 

Specification Status Comment
HTML Living Standard
The definition of 'CanvasRenderingContext2D.drawImage' in that specification.
Living Standard  

Browser compatibility

Update compatibility data on GitHub
DesktopMobile
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidEdge MobileFirefox for AndroidOpera for AndroidiOS SafariSamsung Internet
Basic supportChrome Full support YesEdge Full support 12Firefox Full support YesIE Full support YesOpera Full support YesSafari Full support YesWebView Android Full support YesChrome Android Full support YesEdge Mobile Full support YesFirefox Android Full support YesOpera 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 YesEdge Mobile No support NoFirefox Android Full support 42Opera Android ? Safari 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 59Edge Mobile ? Firefox Android Full support 56Opera Android ? Safari iOS ? Samsung Internet Android Full support 7.0
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 YesEdge Mobile ? Firefox 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

Legend

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

Compatibility notes

  • Support for flipping the image by using negative values for sw and sh was added in Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2).
  • Starting with (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2) drawImage() handles negative arguments in accordance with the specification, by flipping the rectangle around the appropriate axis.
  • Specifying a null or undefined image when calling or drawImage() correctly throws a TYPE_MISMATCH_ERR exception starting with (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2).
  • Prior to Gecko 7.0 (Firefox 7.0 / Thunderbird 7.0 / SeaMonkey 2.4), Firefox threw an exception if any of the coordinate values was non-finite or zero. As per the specification, this no longer happens.
  • Gecko 9.0 (Firefox 9.0 / Thunderbird 9.0 / SeaMonkey 2.6) now correctly supports CORS for drawing images across domains without tainting the canvas.
  • Gecko 11.0 (Firefox 11.0 / Thunderbird 11.0 / SeaMonkey 2.8) now allows SVG-as-an-image to be drawn into a canvas without tainting the canvas.

Notes

  • drawImage() only works correctly on an HTMLVideoElement when its HTMLMediaElement.readyState is greater than 1 (i.e, seek event fired after setting the currentTime property)
  • drawImage() will always use the source element's intrinsic size in CSS pixels when drawing, cropping and/or scaling. For example, if an image is loaded using the constructor's optional size parameters the actual intrinsic size of the bitmap in CSS pixels will still be used.
  • drawImage() will ignore all EXIF metadata in images, including the Orientation. This behavior is espacially troublesome on iOS devices. You should detect the Orientation yourself and use rotate() to make it right.

See also

Document Tags and Contributors

Last updated by: stianjensen,