js优化上传大图片显示问题(压缩图片展示)

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-21 10:58   19   0

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

一、解决方案

上传文件时,发现上传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>

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP