假设我们想将图像大小调整为给定的百分比数。可以从文件输入中确定图像:
<input type="file" id="upload" />
以下函数按百分比比例缩放图像文件:
const resize = (image, ratio) => {
return new Promise((resolve, reject) => {
const reader = new FileReader()
// 读取文件
reader.readAsDataURL(image)
// 监听 load 事件
reader.addEventListener('load', (e) => {
const ele = new Image()
ele.addEventListener('load', () => {
const canvas = document.createElement('canvas')
// 绘制按比例缩放的图像
const context = canvas.getContext('2d')
const w = ele.width * ratio
const h = ele.height * ratio
canvas.width = w
canvas.height = h
context.drawImage(ele, 0, 0, w, h)
// 获取大小调整后的图像数据
'toBlob' in canvas
? canvas.toBlob((blob) => {
resolve(blob)
})
: resolve(dataUrlToBlob(canvas.toDataURL()))
})
ele.src = e.target.result
})
reader.addEventListener('error', (e) => {
reject()
})
})
}
在上面的示例代码中,绘制新图像后,我们必须检查当前浏览器是否支持 canvas
的 toBlob
方法。如果没有,我们必须从 canvas
获取 Data URL。首先 toDataURL()
,然后使用以下函数将其转换为 Blob:
const dataUrlToBlob = (url) => {
const arr = url.split(',')
const mime = arr[0].match(/:(.\*?);/)[1]
const str = atob(arr[1])
let length = str.length
const uintArr = new Uint8Array(length)
while (length--) {
uintArr[length] = str.charCodeAt(length)
}
return new Blob([uintArr], { type: mime })
}
一旦我们有了调整大小的图像的 Blob,我们就可以在前端预览它,或者将其作为 FormData
的一部分发送到后端:
// 获取所选文件
const image = document.getElementById('upload').files[0]
// 预览图像元素
const previewEle = document.getElementById('previewEle')
// 将图像大小调整为 50%
resize(image, 0.5).then((blob) => {
previewEle.src = URL.createObjectURL(blob)
})