您的位置:首页 > Web前端

图片上传显示进度条和预览图的前端实现之预览图篇

2017-06-07 12:01 639 查看
上一集我们说到了进度条的实现,之后就鸽了很久,终于到写这一篇的时候了,说到底一方面是自己太忙,第二方面是自己太懒了。

在图片未上传完成之前不可能拿到上传后返回的uri通过线上地址渲染,同时服务端图片预览虽然也可以实现,但比较麻烦,所以,这里的预览图,其实是拿到本地图片资源后,转换为uri,在浏览器端直接使用。

如图

在上传进度条出现的时候,图片已经出现了,它从何而来呢?

我们可以使用URL.createObjectURl() 这个方法,这个方法通过传入一个File或者Blob对象,返回一个可以作为url的Blob, 我们在上传图片时,通过event.target.files拿到文件传入其中即可

The URL.createObjectURL() static method creates a DOMString containing a URL representing the object given in the parameter. The URL lifetime is tied to the document in the window on which it was created. The new object URL represents the specified File object or Blob object.

objectURL = URL.createObjectURL(object);

贴个简单的例子,这里以单文件上传为例,多文件原理类似。

<input type="file" id='zzxfile' />
<img id='preview' src='' alt=''>

let url;
let img = document.getElementById('preview');
document.getElementById('zzxfile').addEventListener('change', function(e){
if (e.target.files.length) {
img.src = URL.createObjectURL(e.target.files[0])
}

});


但他只兼容ie10,如果要兼容到ie10以前到浏览器,那就。。。木有办法了,可能就需要降级处理,比如Ie的 File对象中的value属性,存储的是要上传的文件的完整路径。可以直接使用,用来兼容一些老的ie浏览器。



当然还可以使用fileReader API。 不过兼容性依然是只兼容ie10以上,比直接使用URL.createObjectURL麻烦一些,也贴一个小例子

<input type="file" id='zzxfile' >
<img id='preview' src='' alt=''>

let url;
let img = document.getElementById('preview');
let reader = new FileReader();
document.getElementById('zzxfile').addEventListener('change', function(e){
if (e.target.files.length) {
reader.onload = function(e){
img.src = e.target.result
}
reader.readAsDataURL(file);
});


做完这一切其实就差不多了,但是,pm大大可能会提出额外需求, 比如我做的是一个图集,为了整齐排列且好看,所有图片都是写死为110 x 110 像素, 预览图也是,那么有些图片可能长宽比例差的比较多,显示出的预览图就会很丑,那么。还得额外裁图,这里我用的是canvas的方法,贴出代码意思一下。

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const img = document.getElementById('zzximg');    // 实际接收从URL.createObjectURL传过来url的img标签。
const previewImg = document.getElementById('preview');   // 接受裁剪后传过来的url的img标签
img.onload = function() {
const imgW = img.offsetWidth;
const imgH = img.offsetHeight;
let x = 0;
let y = 0;
let wh = 0;
if (imgW > imgH) {
x = Math.floor((imgW - imgH) / 2);
wh = imgH;
} else {
y = Math.floor((imgH - imgW) / 2);
wh = imgW;
}
ctx.drawImage(img, x, y, wh, wh, 0, 0, 220, 220);   // 裁剪多一倍进行缩放,保证预览图清晰
const imgSrc = canvas.toDataURL('image/png');
ctx.clearRect(0, 0, canvas.width, canvas.height);
previewImg.src = imgSrc;
img.style.display = 'none';
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息