请使用firefox,chrome等最新浏览器浏览本站。

canvas实现图片压缩上传总结

html5 阿豹 499次浏览 0个评论 扫描二维码

最近在移动项目中遇到了上传图片文件太大的问题。之前实现图片压缩是将数据传到php,php通过gd库实现压缩,显然未经过压缩的数据需要网络上传。 h5 canvas可以实现前端压缩,然后将压缩过的图片传给后台。 这样就减小了网路压力。具体实现方式:

function fileSelected(obj) {
	if (obj) {
		var file = obj.files[0];
		if(ImgCompress.checkType(file)){
			ImgCompress.getBase64(file, obj, getBase);
		}
	}
}

function getBase(data){
	alert(data);
}

var ImgCompress = {

	checkType : function(file){
		if (!file.type.match('image.*')) {
			return false;
		}else{
			return true;
		}
	},

	getBase64 : function(file, obj, callBack){
		var _this = this;
		_this.readFile(file, obj, callBack);
	},

	readFile : function(file, obj, callBack){
		var _this = this;
		var parObj = $(obj).parents(".td");
		var progress =  parObj.find(".progress");
		var img = parObj.find("img");
		var size = file.size;

		//读取文件
		if (window.FileReader) {
			var fr = new FileReader();
			fr.onloadstart = function(e) {
				progress.show();
			};
			fr.onloadend = function(e) {
				progress.hide();
				progress.css("width", "0%");

				//显示图片
				var src = e.target.result;
				img.attr("src", src);

				//压缩图片获取base64编码
				_this.compress(src, callBack);
				
			};
			fr.onprogress = function(e) {
				var pre = e.loaded / size * 100;
				progress.css("width", pre+"%");
			};
			fr.readAsDataURL(file);
		} else {
			alert("请使用高版本浏览器!");
		}
	},

	compress : function(src, callBack){
		var _this = this;
		var img = new Image();
		img.src = src;
		img.onload = function() {  
                //生成比例 
                var width = img.naturalWidth,  
                height = img.naturalHeight,  
                scale = width / height;  
                width = parseInt(750);  
                height = parseInt(width / scale);  

                //生成canvas  
                var $canvas = document.createElement("canvas");
                var ctx = $canvas.getContext('2d'); 
                $canvas.width = width;
                $canvas.height = height;

                //压缩
                ctx.drawImage(img, 0, 0, width, height);  
                callBack( $canvas.toDataURL('image/jpeg',0.5).substr(22));
        } 
    }
};

需要注意的地方:
1.使用FileReader,部分android浏览器的input type=file无法点击,需要设置webview。
2.使用FileReader,部分android浏览器的webview中无法获取图片类型。 需要原生方法实现。
3.对于jsonp实现跨域上传图片,应避免使用。因为jsonp上传是通过url传数据,url的大小有限制,容易赵成上传失败。
4.对于必须使用jsonp实现跨域上传图片的。可以使用断点续传。
具体方法:给数据流添加一个开始和结束的字符串,来告诉后端上传开始和结束。每次后台要给你返回一个结果,如果这一次传失败,你要回滚到上个i继续传。


喜欢 (5)or分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到