JavaScript + Canvas 裁剪图片
JavaScript 操作 DOM Canvas 实现裁剪图片。常用 3 种保持图片长宽比的裁剪方法:
- cover(保证图片的短边显示出来)
- contain(保证图片的长边显示出来)
- fill(拉伸图片)
Cover
把短边找出来,基于短边缩放裁剪窗口。
function clipCoverImage(w: number, h: number, clipw: number, cliph: number) {
const scale = w < h ? clipw / w : cliph / h
const [centerX, centerY] = [w / 2, h / 2]
const [srcClipW, srcClipH] = [clipw / scale, cliph / scale]
return {
sx: centerX - srcClipW / 2,
sy: centerY - srcClipW / 2,
sw: srcClipW,
sh: srcClipH,
}
}
Contain
和上方反过来,基于长边缩放裁剪窗口。实现方法和上方一样,只是缩放基于长边。
- w < h
+ w > h
+ function clipCotainImage(w: number, h: number, clipw: number, cliph: number) {
+ const scale = w > h ? clipw / w : cliph / h
const [centerX, centerY] = [w / 2, h / 2]
const [srcClipW, srcClipH] = [clipw / scale, cliph / scale]
return {
sx: centerX - srcClipW / 2,
sy: centerY - srcClipW / 2,
sw: srcClipW,
sh: srcClipH,
}
}
E.g. 制作缩略图
function makeThumbnail(imgsrc: string, contentType: string, quality: number) {
return new Promise((resolve, reject) => {
const img = createElement('img')
img.crossOrigin = 'anonymous'
img.onload = () => {
const canvas = createElement('canvas')
const ctx = canvas.getContext('2d')
const [clipw, cliph] = [200, 100]
const { sx, sy, sw, sh } = clipCoverImage(img.width, img.height, clipw, cliph)
canvas.hidden = true
canvas.style.display = 'none'
canvas.width = clipw
canvas.height = cliph
ctx.drawImage(img, sx, sy, sw, sh, 0, 0, clipw, cliph)
document.body.appendChild(canvas)
const dataUrl = canvas.toDataURL(contentType, quality)
document.body.removeChild(canvas)
resolve(dataUrl)
}
img.onerror = reject
img.src = imgsrc
})
}