前兩天公司業(yè)務(wù)上有需求需要將較大的圖片壓縮后再傳到遠程服務(wù)器神得,網(wǎng)上找了不少方法都不太好用厘惦,今天有空索性自己寫了一個方法,并把它放到了自己的github上哩簿,有興趣的同學可以戳這里
一宵蕉、需求是什么?
首先想一想我們有哪些需求卡骂?大多時候我們需要將一個File對象壓縮之后再變?yōu)镕ile對象傳入到遠程圖片服務(wù)器国裳;有時候我們也需要將一個base64字符串壓縮之后再變?yōu)閎ase64字符串傳入到遠程數(shù)據(jù)庫;有時候后它還有可能是一塊canvas畫布全跨,或者是一個Image對象缝左,或者直接就是一個圖片的url地址,我們需要將它們壓縮上傳到遠程浓若;面對這么多的需求渺杉,王二索性畫了一張圖:
[圖片上傳失敗...(image-d58aa3-1510824060109)]
二、解決辦法
如上圖所示挪钓,王二一共寫了七個方法是越,基本覆蓋了JS中大部分文件類型的轉(zhuǎn)換與壓縮,其中:
1碌上、urltoImage(url,fn)
會通過一個url加載所需要的圖片對象倚评,其中url
參數(shù)傳入圖片的url
,fn
為回調(diào)方法,包含一個Image對象的參數(shù)浦徊,代碼如下:
function urltoImage (url,fn){
var img = new Image();
img.src = url;
img.onload = function(){
fn(img);
}
};
2、imagetoCanvas(image)
會將一個Image
對象轉(zhuǎn)變?yōu)橐粋€Canvas
類型對象天梧,其中image
參數(shù)傳入一個Image對象盔性,代碼如下:
function imagetoCanvas(image){
var cvs = document.createElement("canvas");
var ctx = cvs.getContext('2d');
cvs.width = image.width;
cvs.height = image.height;
ctx.drawImage(image, 0, 0, cvs.width, cvs.height);
return cvs ;
};
3、canvasResizetoFile(canvas,quality,fn)
會將一個Canvas
對象壓縮轉(zhuǎn)變?yōu)橐粋€Blob
類型對象呢岗;其中canvas
參數(shù)傳入一個Canvas
對象;quality
參數(shù)傳入一個0-1的number
類型冕香,表示圖片壓縮質(zhì)量;fn
為回調(diào)方法,包含一個Blob
對象的參數(shù);代碼如下:
function canvasResizetoFile(canvas,quality,fn){
canvas.toBlob(function(blob) {
fn(blob);
},'image/jpeg',quality);
};
這里的
Blob
對象表示不可變的類似文件對象的原始數(shù)據(jù)后豫。Blob
表示不一定是JavaScript
原生形式的數(shù)據(jù)悉尾。File
接口基于Blob
,繼承了Blob
的功能并將其擴展使其支持用戶系統(tǒng)上的文件挫酿。我們可以把它當做File類型對待构眯,其他更具體的用法可以參考MDN文檔
4、canvasResizetoDataURL(canvas,quality)
會將一個Canvas
對象壓縮轉(zhuǎn)變?yōu)橐粋€dataURL
字符串,其中canvas
參數(shù)傳入一個Canvas
對象;quality
參數(shù)傳入一個0-1的number
類型饭豹,表示圖片壓縮質(zhì)量;代碼如下:
methods.canvasResizetoDataURL = function(canvas,quality){
return canvas.toDataURL('image/jpeg',quality);
};
其中的
toDataURL
API可以參考MDN文檔
5鸵赖、filetoDataURL(file,fn)
會將 File
(Blob
)類型文件轉(zhuǎn)變?yōu)?code>dataURL字符串,其中 file
參數(shù)傳入一個File
(Blob
)類型文件;fn
為回調(diào)方法,包含一個dataURL
字符串的參數(shù);代碼如下:
function filetoDataURL(file,fn){
var reader = new FileReader();
reader.onloadend = function(e){
fn(e.target.result);
};
reader.readAsDataURL(file);
};
6拄衰、dataURLtoImage(dataurl,fn)
會將一串dataURL
字符串轉(zhuǎn)變?yōu)?code>Image類型文件,其中dataurl
參數(shù)傳入一個dataURL
字符串,fn
為回調(diào)方法它褪,包含一個Image
類型文件的參數(shù),代碼如下:
function dataURLtoImage(dataurl,fn){
var img = new Image();
img.onload = function() {
fn(img);
};
img.src = dataurl;
};
7翘悉、dataURLtoFile(dataurl)
會將一串dataURL
字符串轉(zhuǎn)變?yōu)?code>Blob類型對象茫打,其中dataurl
參數(shù)傳入一個dataURL
字符串,代碼如下:
function dataURLtoFile(dataurl) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type:mime});
};
三、進一步封裝
對于常用的將一個File
對象壓縮之后再變?yōu)?code>File對象,我們可以將上面的方法再封裝一下妖混,參考如下代碼:
function fileResizetoFile(file,quality,fn){
filetoDataURL (file,function(dataurl){
dataURLtoImage(dataurl,function(image){
canvasResizetoFile(imagetoCanvas(image),quality,fn);
})
})
}
其中老赤,file
參數(shù)傳入一個File
(Blob
)類型文件;quality
參數(shù)傳入一個0-1
的number
類型制市,表示圖片壓縮質(zhì)量抬旺;fn
為回調(diào)方法,包含一個Blob
類型文件的參數(shù)祥楣。
它使用起來就像下面這樣:
var file = document.getElementById('demo').files[0];
fileResizetoFile(file,0.6,function(res){
console.log(res);
//拿到res开财,做出你要上傳的操作;
})
這樣的話误褪,圖片壓縮上傳就能輕松地搞定了责鳍,以上的8個方法我已經(jīng)封裝好放到github上了,喜歡的話可以使勁的star哈兽间。
參考文檔:
MDN
原文地址:
王玉略的個人網(wǎng)站