Signatur
Beschreibung
drawImage() ist die zentrale Methode, um Rastergrafiken in einen 2D-Canvas zu bringen. Als Quelle eignen sich HTMLImageElement, SVGImageElement, HTMLVideoElement (aktueller Frame), HTMLCanvasElement, OffscreenCanvas, ImageBitmap und VideoFrame.
Es gibt drei Aufrufformen:
drawImage(image, dx, dy)– zeichnet das Bild in Originalgröße an der Position(dx, dy).drawImage(image, dx, dy, dWidth, dHeight)– zeichnet das Bild auf die angegebene Zielgröße skaliert.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)– schneidet einen Ausschnitt (Quellrechteck) aus und zeichnet ihn in das Zielrechteck. Diese Form ist ideal für Sprite-Sheets, Zuschneiden und Zoomen.
Das Zeichnen berücksichtigt den aktuellen Zustand des Kontexts: Transformationen (translate, rotate, scale), globalAlpha, globalCompositeOperation, Clipping-Pfade, Filter und Schatten. Mit imageSmoothingEnabled legst du fest, ob beim Skalieren interpoliert wird. Das ist etwa für Pixel-Art wichtig.
Wichtig: Das Bild muss vollständig geladen sein. Ruft man drawImage() zu früh auf, passiert schlicht nichts, und es gibt auch keinen Fehler. Warte deshalb auf das load-Event oder auf image.decode().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $image Pflicht | HTMLImageElement | SVGImageElement | HTMLVideoElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap | VideoFrame | Die Bildquelle, die gezeichnet werden soll. | |
| $sx | number | 0 | x-Koordinate der oberen linken Ecke des Quellausschnitts (nur in der 9-Argument-Form). |
| $sy | number | 0 | y-Koordinate der oberen linken Ecke des Quellausschnitts (nur in der 9-Argument-Form). |
| $sWidth | number | Breite der Quelle | Breite des Quellausschnitts. |
| $sHeight | number | Höhe der Quelle | Höhe des Quellausschnitts. |
| $dx Pflicht | number | x-Koordinate im Canvas, an der das Bild gezeichnet wird. | |
| $dy Pflicht | number | y-Koordinate im Canvas, an der das Bild gezeichnet wird. | |
| $dWidth | number | sWidth bzw. natürliche Breite | Breite des Bildes im Canvas. Bei Abweichung von der Quellbreite wird skaliert. |
| $dHeight | number | sHeight bzw. natürliche Höhe | Höhe des Bildes im Canvas. Bei Abweichung von der Quellhöhe wird skaliert. |
Rückgabewert
undefined).Beispiele
Bild laden und in Originalgröße sowie skaliert zeichnen
const canvas = document.querySelector('#leinwand');
const ctx = canvas.getContext('2d');
const img = new Image();
img.src = '/bilder/logo.png';
// decode() wartet, bis das Bild zeichenbereit ist
await img.decode();
ctx.drawImage(img, 10, 10); // Originalgröße
ctx.drawImage(img, 200, 10, 100, 50); // auf 100×50 skaliert
console.log(`Gezeichnet: ${img.naturalWidth}×${img.naturalHeight}`);
Sprite-Sheet: einzelnen Frame ausschneiden und animieren
const ctx = document.querySelector('canvas').getContext('2d');
const sprite = new Image();
sprite.src = '/bilder/held-lauf.png'; // 8 Frames à 64×64 nebeneinander
const FRAME = 64;
const FRAMES = 8;
let frame = 0;
const render = () => {
ctx.clearRect(0, 0, 128, 128);
ctx.imageSmoothingEnabled = false; // scharfe Pixel-Art
ctx.drawImage(
sprite,
frame * FRAME, 0, FRAME, FRAME, // Quellausschnitt
0, 0, 128, 128 // Ziel: doppelte Größe
);
frame = (frame + 1) % FRAMES;
setTimeout(() => requestAnimationFrame(render), 100);
};
sprite.addEventListener('load', render);
Video-Frame als Vorschaubild (Thumbnail) exportieren
const video = document.querySelector('video');
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
video.addEventListener('seeked', () => {
canvas.width = 320;
canvas.height = Math.round(320 * video.videoHeight / video.videoWidth);
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
const dataUrl = canvas.toDataURL('image/jpeg', 0.8);
console.log(dataUrl.slice(0, 23));
}, { once: true });
video.currentTime = 5; // zu Sekunde 5 springen
Bild zentriert und gedreht zeichnen
const ctx = document.querySelector('canvas').getContext('2d');
const img = new Image();
img.src = '/bilder/pfeil.png';
await img.decode();
const { width, height } = ctx.canvas;
ctx.save();
ctx.translate(width / 2, height / 2);
ctx.rotate(Math.PI / 4); // 45°
ctx.drawImage(img, -img.width / 2, -img.height / 2);
ctx.restore();
// Wichtig · Fallstricke
- Ladezustand: Ein noch nicht geladenes Bild wird stillschweigend ignoriert. Nutze
await img.decode()oder dasload-Event. Ein Bild mit Status broken wirft einenInvalidStateError. - Tainted Canvas (CORS): Bilder von fremden Ursprüngen ohne CORS-Freigabe „verunreinigen“ den Canvas. Danach werfen
getImageData(),toDataURL()undtoBlob()einenSecurityError. Abhilfe:img.crossOrigin = 'anonymous'setzen, bevorsrczugewiesen wird, und der Server mussAccess-Control-Allow-Originsenden. - Argumentreihenfolge: In der 9-Argument-Form kommen die Quellkoordinaten (
sx, sy, sWidth, sHeight) zuerst. Das ist ein häufiger Verwechslungsfehler. - Unschärfe: Auf hochauflösenden Bildschirmen (
devicePixelRatio > 1) wirken Bilder verwaschen, wenn die interne Canvas-Größe nicht entsprechend hochskaliert wird. Nicht ganzzahlige Koordinaten führen ebenfalls zu Weichzeichnung. - Performance: Bei häufigem Zeichnen ist
createImageBitmap()schneller, weil die Bilddaten bereits dekodiert vorliegen. Große SVG-Bilder bei jedem Frame neu zu rastern ist teuer. - Kompatibilität: Die Methode wird von allen Browsern unterstützt.
VideoFrameundOffscreenCanvasals Quelle gibt es erst in neueren Browserversionen.