目标实现:
1、选择图片, 前端预览效果
2、图片大于1.2M的时候, 对图片进行压缩
3、以表单的形式上传图片
4、图片删除
预览效果图:
代码说明:
1、input:file选择图片
<!-- html部分 --> <ul id="preview" class="clear"> <li class="fl"> <img src="/images/audition/icon_upload.png"> <input id="fileImage" type="file" name="file[]" multiple /> <div class="num">0/4</div> </li> </ul>
var imgId = 0; //图片id标志, 方便删除预览图片 /* 选择图片 */ function choosePic() { $(\'#fileImage\').change(function() { var files = this.files, len = $(\'#preview\').find(\'.pic\').length; if (len + files.length > 4) { showTip(\'最多只能上传4张图片哦~\'); return; } for (var i = 0; i < files.length; i++) { var file = files[i]; if (file.type.indexOf("image") == 0) { if (file.size >= 1024 * 1024 * 3) { showTip(\'图片大小过大,应小于3M\'); } else { showPic(file); //图片预览 } } else { showTip(\'文件"\' + file.name + \'"不是图片类型\') break; } } }); }
2、图片预览(base64)
/* 渲染图片 */ function showPic(file) { var html = \'\', $wap = $(\'#preview\'), reader = new FileReader(); reader.readAsDataURL(file); reader.onload = function(e) { var image_base64 = this.result; html = \'<li class="fl pic" id="imgItem_\' + imgId + \'">\' + \'<img src="\' + image_base64 + \'" alt="">\' + \'<i class="del-img"></i>\' + \'</li>\'; imgId++; $wap.append(html); $(\'#fileImage\').next().text($wap.find(\'.pic\').length + \'/4\'); //图片压缩上传,大于1.2M压缩图片 if (file.size / 1024 > 1024 * 1.2) { dealImage(image_base64, { quality: 0.5 }, function(base64Codes) { var bl = processData(base64Codes, file.type); uploadPic(bl, imgId); }); } else { uploadPic(file, imgId); } } }
3、图片压缩
/** * 图片压缩(利用canvas) * @param path 图片路径 * @param obj 压缩配置width,height,quality,不传则按比例压缩 * @param callback 回调函数 */ function dealImage(path, obj, callback) { var img = new Image(); img.src = path; img.onload = function() { var that = this; // 默认按比例压缩 var w = that.width, h = that.height, scale = w / h; w = obj.width || w; h = obj.height || (w / scale); //生成canvas var canvas = document.createElement(\'canvas\'), ctx = canvas.getContext(\'2d\'); canvas.width = w; canvas.height = h; ctx.drawImage(that, 0, 0, w, h); // 默认图片质量为0.7 var quality = 0.7; if (obj.quality && obj.quality <= 1 && obj.quality > 0) { quality = obj.quality; } // 回调函数返回base64的值 var base64 = canvas.toDataURL(\'image/jpeg\', quality); callback(base64); } }
压缩后的文件是base64格式, 我们希望用file图片的形式上传
/* 将以base64的图片url数据转换为Blob */ function processData(dataUrl, type) { var binaryString = window.atob(dataUrl.split(\',\')[1]), arrayBuffer = new ArrayBuffer(binaryString.length), intArray = new Uint8Array(arrayBuffer); for (var i = 0, j = binaryString.length; i < j; i++) { intArray[i] = binaryString.charCodeAt(i); } var data = [intArray], blob; try { blob = new Blob(data); } catch (e) { window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; if (e.name === \'TypeError\' && window.BlobBuilder) { var builder = new BlobBuilder(); builder.append(arrayBuffer); blob = builder.getBlob(type); } else { showTip(\'版本过低,不支持图片压缩上传\'); } } return blob; }
4、图片上传
/* 上传图片 */ function uploadPic(file, id) { var formData = new FormData(); formData.append(\'img\', file); $.ajax({ url: \'/upload\', type: \'post\', dataType: \'json\', data: formData, contentType: false, processData: false, success: function(res){ if(res.respCode == 1000) { $(\'#imgItem_\' + id).find(\'.del-img\').attr(\'data-src\', res.data.src); }else { showTip(\'文件上传失败!\'); } } }); }
5、其他
function showTip(str) { //TODO:信息提示 console.log(str); }
/* 删除图片 */ function delPic() { var $wap = $(\'#preview\'); $wap.on(\'click\', \'.del-img\', function() { //TODO:从数据库删除图片 $(this).parent().remove(); $(\'#fileImage\').next().text($wap.find(\'.pic\').length + \'/4\'); }); }
源码:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>前端图片预览压缩上传</title> 6 <style> 7 .clear::after { 8 content: \'\'; 9 clear: both; 10 display: block; 11 } 12 .fl { 13 float: left; 14 } 15 .list-img li { 16 position: relative; 17 margin-right: 10px; 18 list-style: none; 19 } 20 .list-img img { 21 display: inline-block; 22 width: 50px; 23 height:50px; 24 } 25 .list-img input { 26 position: absolute; 27 top: 0; 28 left: 0; 29 z-index: 10; 30 width: 50px; 31 height:50px; 32 opacity: 0; 33 } 34 .list-img i { 35 position: absolute; 36 top: 0; 37 right: 0; 38 width: 15px; 39 height: 15px; 40 background: url(../images/icon_del.png) no-repeat center; 41 background-size: 100%; 42 } 43 .list-img .num { 44 position: absolute; 45 left: 0; 46 bottom: 0; 47 width: 100%; 48 text-align: center; 49 color: #999; 50 font-size: 12px; 51 } 52 </style> 53 </head> 54 <body> 55 <div class="list-img"> 56 <ul id="preview" class="clear"> 57 <li class="fl"> 58 <img src="/images/icon_upload.png"> 59 <input id="fileImage" type="file" name="file[]" multiple /> 60 <div class="num">0/4</div> 61 </li> 62 </ul> 63 </div> 64 65 <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> 66 <script> 67 var pageCtrl = { 68 imgId : 0, //图片id标志, 方便删除预览图片 69 maxNum : 4, //最多上传图片张数 70 71 /* 选择图片 */ 72 _choosePic : function() { 73 var _self = this; 74 $(\'#fileImage\').change(function() { 75 var files = this.files, 76 len = $(\'#preview\').find(\'.pic\').length; 77 if (len + files.length > _self.maxNum) { 78 _self._showTip(\'最多只能上传\' + _self.maxNum + \'张图片哦~\'); 79 return; 80 } 81 for (var i = 0; i < files.length; i++) { 82 var file = files[i]; 83 if (file.type.indexOf("image") == 0) { 84 if (file.size >= 1024 * 1024 * 3) { 85 _self._showTip(\'图片大小过大,应小于3M\'); 86 } else { 87 _self._showPic(file); //图片预览 88 } 89 } else { 90 _self._showTip(\'文件"\' + file.name + \'"不是图片类型\') 91 break; 92 } 93 } 94 }); 95 }, 96 97 /* 渲染图片 */ 98 _showPic : function(file) { 99 var _self = this, 100 html = \'\', 101 $wap = $(\'#preview\'), 102 reader = new FileReader(); 103 reader.readAsDataURL(file); 104 reader.onload = function(e) { 105 var image_base64 = this.result, 106 imgId = _self.imgId; 107 108 html = \'<li class="fl pic" id="imgItem_\' + imgId + \'">\' + 109 \'<img src="\' + image_base64 + \'" alt="">\' + 110 \'<i class="del-img"></i>\' + 111 \'</li>\'; 112 imgId++; 113 $wap.append(html); 114 $(\'#fileImage\').next().text($wap.find(\'.pic\').length + \'/\' + _self.maxNum); 115 116 //图片压缩上传,大于1.2M压缩图片 117 if (file.size / 1024 > 1024 * 1.2) { 118 _self._dealImage(image_base64, { 119 quality: 0.5 120 }, function(base64Codes) { 121 var bl = _self._processData(base64Codes, file.type); 122 _self._uploadPic(bl, imgId); 123 }); 124 } else { 125 _self._uploadPic(file, imgId); 126 } 127 } 128 }, 129 130 131 /** 132 * 图片压缩(利用canvas) 133 * @param path 图片路径 134 * @param obj 压缩配置width,height,quality,不传则按比例压缩 135 * @param callback 回调函数 136 */ 137 _dealImage : function(path, obj, callback) { 138 var img = new Image(); 139 img.src = path; 140 img.onload = function() { 141 var that = this; 142 // 默认按比例压缩 143 var w = that.width, 144 h = that.height, 145 scale = w / h; 146 w = obj.width || w; 147 h = obj.height || (w / scale); 148 149 //生成canvas 150 var canvas = document.createElement(\'canvas\'), 151 ctx = canvas.getContext(\'2d\'); 152 canvas.width = w; 153 canvas.height = h; 154 ctx.drawImage(that, 0, 0, w, h); 155 156 // 默认图片质量为0.7 157 var quality = 0.7; 158 if (obj.quality && obj.quality <= 1 && obj.quality > 0) { 159 quality = obj.quality; 160 } 161 162 // 回调函数返回base64的值 163 var base64 = canvas.toDataURL(\'image/jpeg\', quality); 164 callback(base64); 165 } 166 }, 167 168 /* 将以base64的图片url数据转换为Blob */ 169 _processData : function(dataUrl, type) { 170 var binaryString = window.atob(dataUrl.split(\',\')[1]), 171 arrayBuffer = new ArrayBuffer(binaryString.length), 172 intArray = new Uint8Array(arrayBuffer); 173 for (var i = 0, j = binaryString.length; i < j; i++) { 174 intArray[i] = binaryString.charCodeAt(i); 175 } 176 177 var data = [intArray], blob; 178 179 try { 180 blob = new Blob(data); 181 } catch (e) { 182 window.BlobBuilder = window.BlobBuilder || 183 window.WebKitBlobBuilder || 184 window.MozBlobBuilder || 185 window.MSBlobBuilder; 186 if (e.name === \'TypeError\' && window.BlobBuilder) { 187 var builder = new BlobBuilder(); 188 builder.append(arrayBuffer); 189 blob = builder.getBlob(type); 190 } else { 191 _showTip(\'版本过低,不支持图片压缩上传\'); 192 } 193 } 194 return blob; 195 }, 196 197 /* 上传图片 */ 198 _uploadPic : function(file, id) { 199 var _self = this, 200 formData = new FormData(); 201 formData.append(\'img\', file); 202 $.ajax({ 203 url: \'/upload\', 204 type: \'post\', 205 dataType: \'json\', 206 data: formData, 207 contentType: false, 208 processData: false, 209 success: function(res){ 210 if(res.respCode == 1000) { 211 $(\'#imgItem_\' + id).find(\'.del-img\').attr(\'data-src\', res.data.src); 212 }else { 213 _self._showTip(\'文件上传失败!\'); 214 } 215 } 216 }); 217 }, 218 219 /* 删除图片 */ 220 _delPic : function() { 221 var _self = this, 222 $wap = $(\'#preview\'); 223 $wap.on(\'click\', \'.del-img\', function() { 224 //TODO:从数据库删除图片 225 $(this).parent().remove(); 226 $(\'#fileImage\').next().text($wap.find(\'.pic\').length + \'/\' + _self.maxNum); 227 }); 228 }, 229 230 _showTip : function(str) { 231 //TODO信息提示 232 console.log(str); 233 }, 234 235 init: function() { 236 this._choosePic(); 237 this._delPic(); 238 } 239 }; 240 241 $(function() { 242 pageCtrl.init(); 243 }); 244 </script> 245 </body> 246 </html> 247 248 完整代码
参考文章:
https://www.cnblogs.com/007sx/p/7583202.html