简言
记录下使用canvas来压缩图片的实现方式。
图片压缩
有的时候会遇到图片压缩的场景,我们可以使用canvas重新绘制图片,然后利用canvas的toDataURL()API导出base64数据实现图片压缩。
canvas图片压缩原理:
- canvas重新绘制图片可以控制绘制图片的大小,进而改变绘制图片的像素数据。
- canvas的toDataURL()API可以控制导出图片质量,改变图片的大小。
实现
我个人实现了一个简单的demo,你可以根据需要自行修改。
demo实现步骤:
- 获取图片
- 创建canvas和img元素,然后将img元素绘制到canvas上
- 使用canvas导出图片
- 提供下载
获取图片
获取图片主要是获取图片的地址。
我是用input元素获取图片,这样可以本地上传图片。
然后监听input的change事件获得文件对象(图片)。
<input type="file" accept="image/*" id="file">
绘制图片
使用canvas上下文的drawImage()方法绘制,方便控制大小。
具体参考:MDN的drawImage
const img = new Image()img.src = fileBlobimg.onload = function (e) {console.log(img, img.width, 'img');const canvas = document.createElement('canvas')canvas.width = img.widthcanvas.height = img.heightconst ctx = canvas.getContext('2d')ctx.drawImage(img, 0, 0, canvas.width, canvas.height)}
导出图片
利用canvas的toDataURL()API导出图片,它有两个参数:
- 参数1:导出类型
- 参数2:图片质量(0-1)1质量最高,0最差。
具体参考:MDN的toDataURL
data = canvas.toDataURL(imgType, 0.5)
图片下载
利用a链接下载。(适合大部分浏览器,兼容性自行实现)
download.onclick = function () {console.log(data, 'data');const a = document.createElement('a')a.href = dataa.download = imgNamea.type = imgTypea.click()}
源码
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>图片压缩</title>
</head><body><div><input type="file" accept="image/*" id="file"><div><div><span>压缩前:</span><span id="before-size"></span></div><div><span>压缩后:</span><span id="after-size"></span></div></div><div><button id="download">下载</button></div></div><script>const file = document.getElementById('file')const download = document.getElementById('download')const beforeSize = document.getElementById('before-size')const afterSize = document.getElementById('after-size')let data = null // 压缩后的图片let imgName = ''let imgType = ''file.onchange = function (e) {console.log(e.target.files);const files = e.target.filesfor (let i = 0; i < files.length; i++) {const file = files[i]console.log(file, 'file');imgName = file.nameimgType = file.typebeforeSize.innerHTML = file.size / 1024 + 'KB'const fileBlob = URL.createObjectURL(file)const img = new Image()img.src = fileBlobimg.onload = function (e) {console.log(img, img.width, 'img');const canvas = document.createElement('canvas')canvas.width = img.widthcanvas.height = img.heightconst ctx = canvas.getContext('2d')ctx.drawImage(img, 0, 0, canvas.width, canvas.height)data = canvas.toDataURL(imgType, 0.5)console.log(getBase64Size(data, imgType), 'data.size');afterSize.innerHTML = getBase64Size(data, imgType) + 'KB'}}}download.onclick = function () {console.log(data, 'data');const a = document.createElement('a')a.href = dataa.download = imgNamea.type = imgTypea.click()}// 获取base64数据的大小,单位kbfunction getBase64Size(base64, type) {if (!base64) {return 0}if (base64.indexOf(';base64,') === -1) {return 0}base64 = base64.replace('data:' + type + ';base64,', '')if (base64.length % 4 === 0) {base64 = base64.replace(/=+$/, '')}return (base64.length - base64.length / 8 * 2) / 1024}</script>
</body></html>
示例图
结语
结束了。