在項目中經(jīng)常遇到需要將本地圖片上傳至服務(wù)端的情況,免不了要本地預(yù)覽選擇的圖片,圖片太大的情況下還需要對圖片進(jìn)行一番壓縮,通過最近做的項目,對這幾種圖片處理情況做一個總結(jié)。
本文主要解決的問題:
1.圖片在線預(yù)覽功能
2.圖片壓縮
3.通過formData 對象上傳圖片
圖片在線預(yù)覽功能:
需要了解的內(nèi)容:
FileReader 對象
html5為讀取上傳文件的數(shù)據(jù)所提供的對象,它包含以下幾個方法:
readAsBinaryString(Blob/file):把文件內(nèi)容以二進(jìn)制的方式讀取,并放在FileReader的result屬性中,它接受Blob對象或者文件對象。
readAsText(Blob/file, "utf-8"):把文件內(nèi)容以文本字符串的方式讀取,并放在FileReader的result屬性中,它接受Blob對象或者文件對象。(可以為它指定編碼格式)
readAsDataURL(Blob/file) :把文件內(nèi)容以DataURL的方式讀取,并放在FileReader的result屬性中,它接受Blob對象或者文件對象。
什么是Blob對象?
Blob對象就是選擇文件的原始數(shù)據(jù)類型,它提供slice方法可以讀取原始數(shù)據(jù)中某一塊數(shù)據(jù),如果上次文件較大,可以利用Blob可切割的特性將文件分批次上傳。
我們的主要思路是將選擇的圖片文件轉(zhuǎn)換成DataURL的形式,再把dataURL賦給img標(biāo)簽的src屬性即可,因此我們的第一種方法是利用FileReader 的readAsDataURL方法,轉(zhuǎn)換為我們想要的數(shù)據(jù)格式。
首先,在html里創(chuàng)建一個選取文件的元素:
再創(chuàng)建一個在線預(yù)覽的按鈕和顯示區(qū)域:
js中的操作(readAsDataURL的方式):
varreadAsDataURL=document.querySelector("#readAsDataURL");
varimg=document.querySelector("#img");
readAsDataURL.addEventListener("click",function(){
////獲得文件
varfiles=document.querySelector("#upload").files;
if(files.length>0){
////創(chuàng)建FileReader對象
varreader=newFileReader();
////將文件以dataURL讀取, 把文件放在了reader.result上
reader.readAsDataURL(files[0]);
////讀取完畢,執(zhí)行后續(xù)操作
reader.onload=function(){
img.setAttribute("src",this.result);
}
}
});
除此之外,還可以利用window.URL中的createObjectURL方法,該方法可以生成一個url對象,不僅能實現(xiàn)預(yù)覽功能還可以對文件進(jìn)行下載。
varcreateObjectURL=document.querySelector("#createObjectURL");
varimg=document.querySelector("#img");
createObjectURL.addEventListener("click",function(){
varfiles=document.querySelector("#upload").files;
if(files.length){
varurl=window.URL.createObjectURL(files[0]);
////可實現(xiàn)圖片預(yù)覽功能
img.setAttribute("src",url);
}
});
下載創(chuàng)建a標(biāo)簽:
vara=document.createElement("a");
a.href=url;
a.download="usual";
a.innerHTML="下載";
////添加到body
document.body.appendChild(a);
圖片壓縮:
思路:
1.讀取圖片 readAsDataURL
2.創(chuàng)建image對象,獲取圖片的原始尺寸大小
3.創(chuàng)建canvas,把圖片付給canvas,繪制,設(shè)置繪制的大小這就相當(dāng)于壓縮canvas.drawImage(img, 0, 0, height, width)
4.把canvas又轉(zhuǎn)成dataURL的形式。壓縮完成
首先以readAsDataURL的方式讀取文件,創(chuàng)建image對象,以便獲取圖片的原始尺寸大?。?/p>
uglify.addEventListener("click",function(){
varfiles=document.querySelector("#upload").files;
varimg=newImage(),single=true;
vartype="";
if(files.length){
varfileReader=newFileReader();
type=files[0].type;
fileReader.readAsDataURL(files[0]);
fileReader.onload=function(){
img.src=this.result;
};
}
});
result賦給img的src后,監(jiān)聽img是否加載完成,進(jìn)行下一步操作:
img.onload=function(){
////因為后面會再次修改img的src屬性,為了避免死循環(huán)
if(!single){
return;
}
////獲取原始圖片的寬度和高度
varsheight=img.height;
varswidth=img.width;
////創(chuàng)建canvas
varcanvas=document.createElement("canvas");
varcvs=canvas.getContext("2d");
////縮小圖片的尺寸,等同于壓縮
canvas.height=sheight*0.6;
canvas.width=swidth*0.35;
////在畫布上得到壓縮的圖片
cvs.drawImage(img,0,0,sheight/2,swidth/2);
////type是原圖片的類型
varresultData=canvas.toDataURL(type);
single=false;
img.src=resultData;
document.body.appendChild(img);
};
圖片上傳:
利用formData對象可以使用一系列的鍵值對來模擬一個完整的表單文件,然后用ajax發(fā)送這個表單。
//創(chuàng)建formData對象:
vardata=newFormData();
//添加參數(shù),通過append
varfiles=document.querySelector("#upload").files;
data.append("file",files[0]);
//通過ajax 發(fā)送
varxml=newXMLHttpRequest();
xml.open("post","url");
xml.send(data);
xml.onreadystatechange=function(value){
if(xml.readyState==4){
////......
}
}