JS前端图片压缩,超详细注释!

前端利用JS压缩图片,其便利和实用性不用多说,单是上传至服务器时节省的时间和带宽,就能够让人欲罢不能。

这篇文章真的是站在前辈们的肩膀上写成的,代码也是在他们的代码基础上改的,我改的更容易理解一些。代码主要就是实现图片压缩的的功能,其他设置,界面方面,各位自己按照需求来吧。

因为canvas.toDataURL只能改变JPG格式图片的质量,所有这个目前只能压缩JPG。如有大佬知道如何在web上用JS压缩PNG格式的图片,欢迎留言。


正文开始:

首先说下原理的大概的流程,然后按照流程逐一实现。

File->base64->canvas(利用toDataURL来压缩)->base64(压缩后的)->blob

1. 从input获取文件
2. filereader 将文件转化为base64
3. 创建图片对象,获取处理图片宽高
4. 创建canvas对象,将图片画在canvas对象上,同时可用改变图片尺寸。
5. canvas对象转化为base64,如果图片类型为jpg,可用设置压缩比例
6. base64可用直接显示在页面上,如果要传至后台,需要转化为为blob

 

下面用代码逐步实现,步骤都在注释之中,欢迎各位大佬评论留言:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	<input type="file" id="file">
	<img src="" alt="" id='img'>
</body>
</html>
<script>
	// 获取要操作的元素
	var ofile = document.getElementById('file');
	// 声明保存图片base64数据的变量
	var file_base64 = '';
	/**
	 * 定义一些配置
	 * quality  图片压缩的质量大小  值取  0-1 中的一位小数
	 * width   	压缩后的图片宽度,默认0,即为原宽度
	 * height 	压缩后的图片高度,默认0,即为原高度
	 * lockScale 是否锁定宽高比,如果锁定且设定了width,那高度将按照原图片比较自动设定
	 */
	var param = {'quality':0.6, 'width':0, 'height':0, 'lockScale':false};
	// 当ofile发送改变时触发
	ofile.onchange = function(){
		// 步骤1,获取图片文件
		var file = document.getElementById('file').files[0];
		// 步骤2,利用fileReader把文件转化为base64。fileReader是JS内置的一个对象,具体用法可用搜下。
		// 创建fileReader对象
		var fileReader = new FileReader();
		// fileReader把文件转化为base64,让文件读取完成后,会触发FileReader的onload方法。
		fileReader.readAsDataURL(file);
		// 在onload方法中处理后续事件
		fileReader.onload = function(event) {
			// 步骤3. 创建图片对象,获取处理图片宽高,方便后面计算压缩率
			file_base64 = this.result;
			var size = convertBase64UrlToBlob(file_base64).size;
			// 新建一个图像对象,用来获取老图片的原始尺寸
			var img = new Image();
			img.src = file_base64;

			// 在图片完成加载后继续处理后面的
			img.onload = function(){
				// 获取图片的宽高
				var img_width = this.width;
				var img_height = this.height;
				// 步骤4,创建canvas,用这个的目的,一是drawImage方法可用改变图片的尺寸,二是toDataURL可用改变图片的质量,达到压缩的目的
				// toDataURL只能改变JPG的质量,但是这段代码偶尔也能压缩PNG,有时变大,有时变小,比较随缘。
				var canvas = document.createElement('canvas');
				var ctx = canvas.getContext('2d');

				// 根据先前定义的配置来获得最终的图片尺寸,纯逻辑计算,不再详细解释
				var final_width = param.width || img_width;
				var final_height = '';

				if (param.lockScale) {
					var scale = img_width/img_height;
					final_height = img_width/scale;
				} else {
					final_height = param.height || img_height;
				}

				// 利用createAttribute和setAttributeNode为canvas添加宽高,如果对这个有点懵逼,请自行复习JS基础
				var cwa = document.createAttribute('width');
				cwa.nodeValue = final_width;
				canvas.setAttributeNode(cwa);
				var cwh = document.createAttribute('height');
				cwh.nodeValue = final_height;
				canvas.setAttributeNode(cwh);
				// 将图片画在cancas上,drawImage的具体用法,不懂可用自己查
				// 下面一句话意思就是把修改尺寸后的图片不做裁剪的画在canvas上
				ctx.drawImage(this, 0, 0, final_width, final_height);
				// 步骤5,把canvas转化为base64,可用直接当做图片链接使用
				// 这里直接写死了image/jpeg类型,其实这个也可用设置为变量
				file_base64 = canvas.toDataURL('image/jpeg', param.quality);
				// 步骤6,将base64塞入img标签中进行预览
				document.getElementById('img').src = file_base64;
				// 将base64转化为blob,如果图片需要上传至后台,则需要这一步,然后再利用FormData进行上传
				var blob = convertBase64UrlToBlob(file_base64);
				// 计算图片压缩比
				console.log('原大小:'+size);
				console.log('现大小:'+blob.size);
				var rate = ((blob.size/size) * 100).toFixed(2);
				console.log('压缩率:'+ rate + '%');
			}


			
		}
		// 图片读取失败的回调
		fileReader.onerror = function(event) {
			console.log(event);
			alert('图片解析错误');
		}
	}
	// 将base64转化为blob
	function convertBase64UrlToBlob(urlData){
	    var arr = urlData.split(','), mime = arr[0].match(/:(.*?);/)[1],
	        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
	    while(n--){
	        u8arr[n] = bstr.charCodeAt(n);
	    }
	    return new Blob([u8arr], {type:mime});
	}
</script>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值