前端图片压缩
前几天做项目,由于要上传大量的扫描图片,为了加快上传速度,就自然而然的想到了图片压缩,最近有了点时间就整理了下代码,贴出来以备后用。
在压缩图片的过程中主要使用了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>
学如逆水行舟,不进则退!
与诸君共勉!