图片压缩
前端图片压缩
前几天做项目,由于要上传大量的扫描图片,为了加快上传速度,就自然而然的想到了图片压缩,最近有了点时间就整理了下代码,贴出来以备后用。
在压缩图片的过程中主要使用了FileReader 、canvas、以及base64长度的计算,整个功能的思路并不复杂,实现过程大致如下:
(1) 用户上传的时候通过input onchange事件拿到file对象,然后把file对象通过 FileReader转成base64字符串
(2)新建img对象 把数据赋值到img对象
(3)新建canvas对象 用canvas.toDataURL() 实现压缩
代码并不复杂,但是还是小小的踩了几个坑的,详细代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>图片转base64</title> </head> <body> <input type="file" id="file"> <img src="" id="testimg" alt=""> </body> <script> document.getElementById('file').onchange = function(e) { var file = e.target.files[0]; toBase64(file) } function toBase64(file) { var name = file.name //文件名 var size = file.size //文件的字节大小。 var type = file.type //字符串类型,文件的MIME类型。 var reader = new FileReader(); //reader对象 var imgurl = ''; reader.readAsDataURL(file); //并将文件数据以URL形式保存到result属性中 reader.onloadend = function(e) { imgurl = e.target.result; //base64字符串 canvasDataUrl(imgurl, file, 1000, 800 * 1024, objDiv) //压缩图片 } } function objDiv(base64) { document.getElementById('testimg').src = base64; } function computedSize(base64Str) { //计算base64字符串字节大小 base64 = base64Str.split(',')[1]; //去掉前缀 base64.replace(/=/g, ''); //去除= var length = base64.length; return length - length / 8 * 2; } function canvasDataUrl(imgurl, file, maxPixeSize, maxBateSize, callback) { // imgurl:原图片runder之后得base64;file: 原图片file对象, maxPixeSize:压缩图片后最大像素尺寸, maxBateSize//压缩后输出的最大字节 var img = new Image(); if (computedSize(imgurl) < maxBateSize) { callback.call(null, imgurl); return; } console.log('压缩前大小:' + file.size) img.src = imgurl; img.onload = function() { var that = this; var w = that.width, h = that.height, scale = w / h; //宽高比 var quality = 1; var canvas = document.createElement('canvas'); var max_Szie = Math.max(w, h); //尺寸压缩 if (max_Szie > maxPixeSize) { //计算比例 quality = maxPixeSize / max_Szie } var new_width = w * quality; var new_height = h * quality; canvas.width = new_width; canvas.height = new_height; var ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, new_width, new_height) ctx.drawImage(that, 0, 0, new_width, new_height); var arr = imgurl.split(','); var mine = arr[0].match(/:(.*?);/)[1]; //文件类型 :image/jpeg jpg为例 var base64UrlPrefix = arr[0] + ','; //data:image/jpeg;base64, jpg为例 var Ratio = 0.9; //压缩比率 if (computedSize(imgurl) > 1024 * 1024) { Ratio = 0.6; } jpegURL = canvas.toDataURL(mine, Ratio).replace(/^.*?,/, ''); //只保留字符串部分 if (window.atob(jpegURL).length > maxBateSize) { Ratio = 0.3; jpegURL = canvas.toDataURL(mine, Ratio).replace(/^.*?,/, ''); } img = null; canvas = null; if (typeof callback == 'function') { // 回调函数返回base64的值 callbackurl = base64UrlPrefix + jpegURL; callback.call(null, callbackurl); //参数压缩后的base64 } } } </script> </html>
学如逆水行舟,不进则退!
与诸君共勉!