|
亲测有效,下面是上传后的图片加载时间以及压缩图片加载时间。

一、解决方案
上传文件时,发现上传4M的图片,上传时有进度条,但是进度条结束之后,加载图片耗时917ms,当用户焦急的盯着进度条结束后,还要等上传之后的图片加载时间,这期间没有任何提示信息。
优化方案:在文件上传后,获取文件流,进行压缩图片,优先展示压缩后的图片,然后把上传成功的图片进行替换,图片展示由模糊到清晰的,在用户未察觉之前,偷梁换柱。(以下,只js前端处理,具体上传逻辑不做说明)
上传之后的图片:

原图:

透明图片:

代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>upload</title> <script src="https://csdnimg.cn/public/common/libs/jquery/jquery-1.9.1.min.js"></script>
</head> <body> <canvas id="canvasNew" width="400px" height="250px"></canvas> <input type="file" id="upLoad" name="image" > </body> <script type="text/javaScript"> // 保存图片路径的数组 var urlArr = ["bg.png"]; // imgArr 保存加载后的图片的数组,imgArr中保存的是真实的图片 // loadImg 函数用来加载 urlArr 中所有的图片 // 并返回一个保存所有图片的数组 var imgArr = loadImg(urlArr); // flag 用来限制 点击事件,一张图片只会产生一次效果 var flag = false;
function loadImg(urlArr) { var index = 0; var res = []; // 每次给 load 函数传入一个图片路径,来加载图片 load(urlArr[index]); function load(url) { // 如果 index 等于 urlArr.length, // 表示加载完 全部图片了,就结束 load函数 if (index == urlArr.length) { // 加载完全部图片,调用 init 函数 //init(); return; }
var img = new Image(); img.src = url; // 不管当前图片是否加载成功,都要加载下一张图片 img.onload = next; img.onerror = function () { console.log(res[index] + "加载失败"); next(); } // next 用来加载下一张图片 function next() { // 把加载后的图片,保存到 res 中 res[index] = img; load(urlArr[++index]) } } // 最后返回保存所有真实图片的数组 return res; }
$(function(){ $('#upLoad').on('change',function(){ var filePath = $(this).val(), //获取到input的value,里面是文件的路径 fileFormat = filePath.substring(filePath.lastIndexOf(".")).toLowerCase(), imgBase64 = '', //存储图片的imgBase64 fileObj = document.getElementById('upLoad').files[0]; //上传文件的对象,要这样写才行,用jquery写法获取不到对象 // 检查是否是图片 if( !fileFormat.match(/.png|.jpg|.jpeg/) ) { alert('上传错误,文件格式必须为:png/jpg/jpeg'); return; } // 调用函数,对图片进行压缩 compress(fileObj,function(imgBase64){ imgBase64 = imgBase64; //存储转换的base64编码 //$('#viewImg').attr('src',imgBase64); //显示上传图片 loadResImg(imgBase64); }); }); 生成图片由模糊到清晰效果 function loadResImg(imgBase64){ var img = new Image(); img.src = imgBase64; var canvasNew = document.getElementById("canvasNew"); var contextNew = canvasNew.getContext("2d"); // 先在canvas上画透明的图片,然后再设置背景是上传的图片 contextNew.globalCompositeOperation = "source-over"; contextNew.drawImage(imgArr[0], 0, 0, 400, 250); canvasNew.style.background = 'url('+imgBase64+')'; canvasNew.style.backgroundSize = "100% 100%"; } //不对图片进行压缩,直接转成base64 function directTurnIntoBase64(fileObj,callback){ var r = new FileReader(); // 转成base64 r.onload = function(){ //变成字符串 imgBase64 = r.result; console.log(imgBase64); callback(imgBase64); } r.readAsDataURL(fileObj); //转成Base64格式 } // 对图片进行压缩 function compress(fileObj, callback) { if ( typeof (FileReader) === 'undefined') { console.log("当前浏览器内核不支持base64图标压缩"); //调用上传方式不压缩 directTurnIntoBase64(fileObj,callback); } else { try { var reader = new FileReader(); var data ; reader.onload = function (e) { var image = new Image(); var imageNew = $('<img/>'); image.οnlοad=function(){ square = 500, //定义画布的大小,也就是图片压缩之后的像素 canvas = document.createElement('canvas'), context = canvas.getContext('2d'), imageWidth = 0, //压缩图片的大小 imageHeight = 0, offsetX = 0, offsetY = 0, data = ''; canvas.width = square; canvas.height = square; context.clearRect(0, 0, square, square); if (this.width > this.height) { imageWidth = Math.round(square * this.width / this.height); imageHeight = square; offsetX = - Math.round((imageWidth - square) / 2); } else { imageHeight = Math.round(square * this.height / this.width); imageWidth = square; offsetY = - Math.round((imageHeight - square) / 2); } context.drawImage(this, offsetX, offsetY, imageWidth, imageHeight); data = canvas.toDataURL('image/jpeg');
//压缩完成执行回调 callback(data); }; image.src= e.target.result; }; reader.readAsDataURL(fileObj); }catch(e){ console.log("压缩失败!"); //调用直接上传方式 不压缩 directTurnIntoBase64(fileObj,callback); } } }
});
</script> </html>
|