因项目需求要做一个单图片上传的功能,本来想直接用webUploader做,但是调样式没哟调出来我想要的效果,就想着自己写一个。
就是这么一个简单的样子,添加图片进行预览,再次点击可以修改图片。 本来开始做好了之后可以上传了,后来发现手机照的照片都在4、5M,很大,上传很慢,让后就加了一个压缩。 本来压缩想使用base64的,然后发现后台不支持,?好尴尬。 look 一下整体代码吧,还是需要jq支持的。整体代码
复制代码
.imgUpload { width: 88px; height: 88px; position: relative;}.imgUpload input[type='file'] { width: 100%; height: 100%; opacity: 0; position: absolute; z-index: 2;}.imgUpload img { width: 100%; height: 100%; position: absolute; z-index: 1;}复制代码
function ImgUpload(ele, files, options ) { this.ele = ele;//点击的input元素 this.files = files;//图片file this.compression = options.compression || false;//是否开启压缩默认否 this.maxWidth = options.maxWidth || 800;//压缩最大宽度 this.maxHeight = options.maxHeight || 800;//压缩最大高度 this.callback = options.callback;//回调 this.init();}ImgUpload.prototype = { init: function () { this.onChangeUploadFile(); }, onChangeUploadFile: function () { var _this = this; //判断文件是否添加进来 if (this.files.length == 0) { return false; } var file = this.files[0]; //判断上传的是不是图片 if (file.type.indexOf('image') === -1) { alert("您上传的不是图片!"); return false; } //上传图片进行最大限制 var filesize = Math.floor((file.size) / 1024); if (filesize > 1024 * 20) { alert("上传大小不能超过20M."); return false; } this.ele.parent().find("img").attr("src", window.URL.createObjectURL(file)); if( !this.compression ) { if (this.callback) { this.callback( file ); } }else { // 压缩图片需要的一些元素和对象 var reader = new FileReader(), img = new Image(); //result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容 reader.readAsDataURL(file); // 文件base64化,以便获知图片原始尺寸 reader.onload = function(e) { img.src = e.target.result; }; // 缩放图片需要的canvas var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); img.onload = function () { // 图片原始尺寸 var originWidth = this.width; var originHeight = this.height; // 最大尺寸限制 var maxWidth = _this.maxWidth, maxHeight = _this.maxHeight; // 目标尺寸 var targetWidth = originWidth, targetHeight = originHeight; // 图片尺寸超过限制 if (originWidth > maxWidth || originHeight > maxHeight) { if (originWidth / originHeight > maxWidth / maxHeight) { // 更宽,按照宽度限定尺寸 targetWidth = maxWidth; targetHeight = Math.round(maxWidth * (originHeight / originWidth)); } else { targetHeight = maxHeight; targetWidth = Math.round(maxHeight * (originWidth / originHeight)); } } // canvas对图片进行缩放 canvas.width = targetWidth; canvas.height = targetHeight; // 清除画布 context.clearRect(0, 0, targetWidth, targetHeight); // 图片压缩 context.drawImage(img, 0, 0, targetWidth, targetHeight); // canvas转为blob返回 canvas.toBlob(function (blob) { if (_this.callback) { _this.callback( blob ); } }, file.type || 'image/png'); }; } }}$('.imgUploadIpt').on('change', function (event) { new ImgUpload($(this), event.target.files, { compression: true, //开启压缩默认不压缩 maxWidth: 600, //开启压缩图片最大宽度 maxHeight: 600, //开启压缩图片最大高度 callback:function (file) {//回调函数 console.log(file); } })})复制代码
压缩不压缩可以配置,压缩的话,压缩图片大小可以配置。
如何上传
上传的话需要建一个FormData把要上传的都放到里面就好了。
var formData = new FormData();formData.append('file','上面拿到的file');formData.append('parameter1', 'parameter1');formData.append('parameter2', 'parameter2');$.ajax({ url: 'URL', type: 'POST', async: false, data: formData, processData: false, contentType: false, success:function (data) { //do something }, error:function (XMLHttpRequest, textStatus, errorThrown) { //do something }});复制代码
遇到问题
在将canvas转为blob返回的时候,发现有些移动端不支持。解决方法直接引入一个js就可以。
参考地址 ;