Canvas Manipulating Images

What You’ll Learn
Canvas can draw images and then manipulate them in two main ways:
- Geometry transforms: scale, rotate, flip, and crop using
drawImage()+ transforms. - Pixel effects: read and modify raw RGBA pixels using
getImageData()/putImageData().
⚡ Quick Reference
Draw & scale
drawImage(img, dx, dy, dw, dh)Scale to dw/dh while drawing
Crop + scale
drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh)Crop source then draw
Pixels
getImageData / putImageDataEdit RGBA values
👀 Live Preview — Crop, Rotate & Filter
This demo generates a sample image (or you can upload one), then lets you crop, rotate, scale, flip, and apply pixel effects.
Tip: pixel effects here use getImageData(). If you draw cross‑origin images without CORS, browsers block pixel reads with a security error.
1
Scale an Image with drawImage()
Scaling is built into drawImage() via destination width/height.
script.js
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = () => {
// Draw image scaled to 200×150
ctx.drawImage(img, 20, 20, 200, 150);
};
img.src = '/images/example.jpg';2
Rotate (Transform) Before Drawing
Rotate around the canvas center by translating first, then rotate, then draw around (0,0).
script.js
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate(Math.PI / 180 * 25);
// draw centered
ctx.drawImage(img, -img.width / 2, -img.height / 2);
ctx.restore();3
Grayscale Filter with getImageData()
Pixel manipulation edits the ImageData.data array (RGBA values in the range 0..255).
script.js
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
data[i] = avg; // R
data[i + 1] = avg; // G
data[i + 2] = avg; // B
}
ctx.putImageData(imageData, 0, 0);💡 Best Practices
Do
- Use
ctx.save()/ctx.restore()around transforms - Use the 9-argument
drawImage()to crop and scale in one step - Cache intermediate results using an offscreen canvas when applying many effects
- Prefer same-origin images (or proper CORS) if you need
getImageData() - Set
imageSmoothingEnabled/imageSmoothingQualitywhen scaling
Don’t
- Forget that transforms are cumulative (always restore)
- Run heavy pixel loops every frame on large canvases without profiling
- Assume uploaded/cross-origin images always allow pixel reads
- Mutate
ImageData.datawithout clamping to 0..255 - Over-allocate new ImageData each time when you can reuse buffers
❓ Frequently Asked Questions
Use
drawImage(img, x, y, width, height). The destination width/height scales the image.Use
drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh) to crop a source rectangle then draw it to the destination.If the canvas is tainted by a cross-origin image without CORS headers, browsers block pixel reads for security.
Use
ctx.filter for simple effects while drawing. Use pixel manipulation for custom effects (but it can be slower).Next: Canvas Pattern
Create repeating fills and textures using createPattern().
4 people found this page helpful
