Canvas图像处理完整教程,掌握图像绘制、裁剪、缩放、滤镜等核心功能。Canvas提供了强大的图像处理能力,包括图像绘制、裁剪、缩放和像素操作。
drawImage方法有多种调用形式:
| 语法 | 说明 |
|---|---|
| drawImage(image, x, y) | 原始尺寸绘制 |
| drawImage(image, x, y, width, height) | 缩放绘制 |
| drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) | 裁剪绘制 |
| 类型 | 说明 |
|---|---|
| HTMLImageElement | img元素 |
| HTMLVideoElement | video元素 |
| HTMLCanvasElement | canvas元素 |
| ImageBitmap | 位图对象 |
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
const img = new Image()
img.onload = function() {
// 原始尺寸绘制
ctx.drawImage(img, 0, 0)
}
img.src = 'image.png'
img.onload = function() {
// 缩放到指定尺寸
ctx.drawImage(img, 0, 0, 200, 150)
// 放大
ctx.drawImage(img, 220, 0, 400, 300)
}
img.onload = function() {
// 从源图像(50, 50)位置裁剪100x100区域
// 绘制到画布(0, 0)位置,尺寸200x200
ctx.drawImage(img, 50, 50, 100, 100, 0, 0, 200, 200)
}
// 水平翻转
ctx.save()
ctx.scale(-1, 1)
ctx.drawImage(img, -img.width, 0)
ctx.restore()
// 垂直翻转
ctx.save()
ctx.scale(1, -1)
ctx.drawImage(img, 0, -img.height)
ctx.restore()
// 旋转图像
ctx.save()
ctx.translate(canvas.width / 2, canvas.height / 2)
ctx.rotate(Math.PI / 4) // 旋转45度
ctx.drawImage(img, -img.width / 2, -img.height / 2)
ctx.restore()
异步创建ImageBitmap对象,提高性能:
// 从图像创建
const bitmap = await createImageBitmap(img)
ctx.drawImage(bitmap, 0, 0)
// 从Blob创建
const response = await fetch('image.png')
const blob = await response.blob()
const bitmap = await createImageBitmap(blob)
ctx.drawImage(bitmap, 0, 0)
// 裁剪创建
const croppedBitmap = await createImageBitmap(img, 50, 50, 100, 100)
ctx.drawImage(croppedBitmap, 0, 0)
const video = document.querySelector('video')
function drawFrame() {
ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
requestAnimationFrame(drawFrame)
}
video.addEventListener('play', drawFrame)
// 启用图像平滑(默认)
ctx.imageSmoothingEnabled = true
ctx.imageSmoothingQuality = 'high' // low, medium, high
// 禁用图像平滑(像素化效果)
ctx.imageSmoothingEnabled = false
跨域问题
// 图像需要设置crossOrigin属性
const img = new Image()
img.crossOrigin = 'anonymous'
img.onload = function() {
ctx.drawImage(img, 0, 0)
}
img.src = 'https://example.com/image.png'
图像加载状态
// 确保图像加载完成
if (img.complete) {
ctx.drawImage(img, 0, 0)
} else {
img.onload = function() {
ctx.drawImage(img, 0, 0)
}
}
性能优化
// 预加载图像
const images = {}
function preloadImages(sources, callback) {
let loaded = 0
const total = Object.keys(sources).length
Object.keys(sources).forEach(key => {
const img = new Image()
img.onload = function() {
images[key] = img
loaded++
if (loaded === total) callback()
}
img.src = sources[key]
})
}
内存管理
// ImageBitmap需要手动释放
let bitmap = await createImageBitmap(img)
ctx.drawImage(bitmap, 0, 0)
bitmap.close() // 释放内存