【前端】图片回显和压缩

本篇主要实现

  • 前端回显上传图片
  • 前端压缩上传图片质量

主要使用技术

  1. window.URL.createObjectURL
  2. FileReader
  3. 滤镜IE9以下
  4. html5 canvas

代码如下

  • index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8" />
<title>图片上传-前端回显图片-模拟图片选择控件-前端压缩</title>
<style>
</style>

<script type="text/javascript" src="index.js"></script>
</head>
<body>
    <!-- 隐藏 file input控件 -->
	<!-- 方法1:style="width:0;height:0;" 兼容ie9 ie9-,其他浏览器可以设置为display:none -->
	<!-- 方法2:style="position:fixed;left:-99999px;" 移出显示区域 -->
	<input type="file" name="file" style="position:fixed;left:-99999px;" accept="image/jpg,image/jpeg,image/png" onchange="picPreview(this)" />
	<div onclick="selectPic()"  style="width:541px; height:361px; border: 1px solid black;">
	    <img id="preview" style="display:block;" width="540" height="360" alt="点击选择图片" />
	</div>
	<div>压缩后展示:</div>
</body>

</html>
  • index.js
var selectPic = function(imgPreview) {
	// 点击选择图片后出发input file的click事件
	document.getElementsByName("file")[0].click();
}

var picPreview = function(imgObj) {
	var accepts = imgObj.accept;
	// chrome63 选择上传图片后,再次点击浏览,但不选择图片,会导致上次选择的内容被清除
	try {
		if(imgObj.files.length == 0) {
			return;
		}
		var suffix = getSuffix(imgObj.files[0].name);
		// firefox5.0 不支持 str.startsWith,因此使用indexOf判断
		if (!imgObj.files[0] || -1 == accepts.indexOf(suffix)) {
			alert("请重新选择图片,格式应为" + accepts);
			imgObj.outerHTML = imgObj.outerHTML;// 重新初始化img,即清除已选择的文件
			document.getElementById("preview").src = "";// 清空预览图
			return;
		}
		// https://developer.mozilla.org/zh-CN/docs/Web/API/Window/URL
		window.URL = window.URL || window.webkitURL;
		var imgSrc = window.URL.createObjectURL(imgObj.files[0]);
		document.getElementById("preview").src = imgSrc;
		
		// FileReader
		var freader = new FileReader();
		freader.readAsDataURL(imgObj.files[0]);
		freader.onload = function(e) {
			document.getElementById("preview2").src = e.target.result;
		};
		
		var oldSize = imgObj.files[0].size;
		console.log("原文件大小: " + imgObj.files[0].size);
		var canvas = document.createElement("canvas");
		
		var imgtype = "image/jpeg";//image/png, image/jpg 压缩效果不如意
		var cps = 0.34; //质量
		
		if (canvas.getContext) {// 支持canvas,可以做压缩图片(质量压缩,分辨率不变(宽*高))
			document.getElementById("preview").onload = function() {
				var w = this.naturalWidth;
				var h = this.naturalHeight;
				canvas.width = w;
				canvas.height = h;
				var d2 = canvas.getContext("2d");
				d2.clearRect(0, 0, w, h);
				d2.drawImage(this, 0, 0);
				// 仅 image/jpeg 和 image/webp 格式,质量参数才有效(才能压缩图片质量)
				// webp 格式 仅 chrome 支持
				// 1 压缩为base64 字符串
				var dataURL = canvas.toDataURL(imgtype, cps);
				console.log("canvas.toDataURL的大小:" + dataURL.length + ", 压缩比:" + dataURL.length/oldSize);
				// 文件上传 dataURL
				var newdiv = document.createElement("div");
				newdiv.style = "min-width: 500px; min-height: 1500px; ";
				document.body.appendChild(newdiv);
				var newimg = new Image();
				newimg.src = dataURL;
				newdiv.appendChild(newimg);
				var toblob = convertImgDataToBlob(dataURL);
				console.log("dataURL to blob的大小:" + toblob.size + ", 压缩比:" + toblob.size/oldSize);
				// 2 压缩为二进制blob对象
				canvas.toBlob(function(blob){
					console.log("canvas.toBlob的大小 " + blob.size + ", 压缩比:" + blob.size/oldSize);
					//文件上传 blob
				}, imgtype, cps);
			};
		}
	} catch (e) {
		console.log(e);
		if (!imgObj.value) {
			return;
		}
		// not support input-files.files, such as ie9 ie9-
		// select & blur 解决ie9无法直接访问图片
		imgObj.select();
		imgObj.blur();// IE9以下,如果file控件获得焦点,则document.selection.createRange()拒绝访问
		// 使用滤镜
		var path = document.selection.createRange().text;
		if (-1 == accepts.indexOf(getSuffix(path))) {
			alert("请选择图片");
			imgObj.outerHTML = imgObj.outerHTML;// 重新初始化img,即清除已选择的文件
			// 清空滤镜,清空预览图
			document.getElementById("previewOnIe9").src = "";
			document.getElementById("previewOnIe9").style.filter = "";
			return;
		}
		document.getElementById("previewOnIe9").style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale);";
		document.getElementById("previewOnIe9").filters
				.item("DXImageTransform.Microsoft.AlphaImageLoader").src = document.selection
				.createRange().text;
		// 设置img的src为base64编码的透明图片 取消显示浏览器默认图片
		document.getElementById("previewOnIe9").src = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
	}
}

function convertImgDataToBlob(base64Data) {
	var format = "image/jpeg";
	var base64 = base64Data;
	var code = window.atob(base64.split(",")[1]);
	var aBuffer = new window.ArrayBuffer(code.length);
	var uBuffer = new window.Uint8Array(aBuffer);
	for (var i = 0; i < code.length; i++) {
		uBuffer[i] = code.charCodeAt(i) & 0xff;
	}
	var blob = null;
	try {
		blob = new Blob([ uBuffer ], {type: format});
	}
	catch (e) {
		window.BlobBuilder = window.BlobBuilder ||
		    window.WebKitBlobBuilder ||
		    window.MozBlobBuilder ||
		    window.MSBlobBuilder;
		if (e.name == 'TypeError' && window.BlobBuilder) {
			var bb = new window.BlobBuilder();
			bb.append(uBuffer.buffer);
			blob = bb.getBlob("image/jpeg");
		}
		else if (e.name == "InvalidStateError") {
			blob = new Blob([ aBuffer ], {type: format});
		}
		else {
		}
	}
	return blob;
};

var getSuffix = function(name) {
	var suffix = null;
	var index;
	if ((index = name.lastIndexOf(".")) != -1) {
		suffix = name.substring(index + 1);
	}
	return suffix;
}

转载于:https://my.oschina.net/tita/blog/1918030

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值