做H5頁面,調(diào)用相冊圖片文件太大,怎么實現(xiàn)上傳縮略圖或者壓縮圖
趁著中午,大致代碼的我寫一下,供參考:
// 上傳函數(shù)
function upload(e) {
var file = e.target.files[0];
if (!file) return; // 未上傳
var orientation; // 圖片上傳的角度,解決
/**
* 利用exif.js解決ios手機上傳豎拍照片旋轉(zhuǎn)90度問題
* 詳見 http://code.ciaoca.com/javascript/exif-js/
*/
EXIF.getData(file, function () { // 獲取照片方向角屬性,用戶旋轉(zhuǎn)控制
orientation = EXIF.getTag(this, 'Orientation');
});
var reader = new FileReader(); // 讀取文件
reader.onload = function () {
getImgData(this.result, orientation, function (result) {
var img = new Image();
img.src = result;
// 如果圖片大小小于200kb,則直接上傳
if (result.length <= that.minSize) {
ajaxUpload(result, file.type, file.name); // 調(diào)用上傳接口函數(shù)
img = null;
return;
}
// 圖片加載完畢之后進(jìn)行壓縮,然后上傳
if (img.complete) {
callback();
} else {
img.onload = callback;
}
function callback () {
var data = compress(img);
// 文件上傳
ajaxUpload(data, file.type, file.name);
img = null;
}
})
}
reader.readAsDataURL(file);
}
/**
* 圖片上傳,將base64的圖片轉(zhuǎn)成二進(jìn)制對象,塞進(jìn)formdata上傳
* @param {*} basestr
* @param {*} type
*/
function ajaxUpload (basestr, type, name) {
var text = window.atob(basestr.split(',')[1]);
var buffer = new Uint8Array(text.length);
for (var i = 0; i < text.length; i++) {
buffer[i] = text.charCodeAt(i);
}
var blob = getBlob([buffer], type);
var xhr = new XMLHttpRequest();
var formdata = getFormData();
formdata.append('multipartFile', blob, name)
// append 追加還追加其他參數(shù)
xhr.open('post', '請求的url')
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var jsonData = JSON.parse(xhr.responseText)
// 接口返回的 json 數(shù)據(jù) 自行解析
}
if (xhr.status !== 200) {
// 通信失敗
}
}
xhr.send(formdata)
}
/**
* 使用canvas對大圖片進(jìn)行壓縮
* @param {img} 圖片
*/
function compress (img) {
// 用于壓縮圖片的canvas
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// 瓦片canvas
var tCanvas = document.createElement('canvas');
var tctx = tCanvas.getContext('2d');
// let initSize = img.src.length
var width = img.width;
var height = img.height;
// 如果圖片大于四百萬像素,計算壓縮比并將大小壓至400萬以下
var ratio;
if ((ratio = width * height / 4000000) > 1) {
ratio = Math.sqrt(ratio);
width /= ratio;
height /= ratio;
} else {
ratio = 1;
}
canvas.width = width;
canvas.height = height;
// 鋪底色
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 如果圖片像素大于100萬則使用瓦片繪制
var count;
if ((count = width * height / 1000000) > 1) {
count = ~~(Math.sqrt(count) + 1); // 計算要分成多少塊瓦片
// 計算每塊瓦片的寬和高
var nw = ~~(width / count);
var nh = ~~(height / count);
tCanvas.width = nw;
tCanvas.height = nh;
for (let i = 0; i < count; i++) {
for (let j = 0; j < count; j++) {
tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);
ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
}
}
} else {
ctx.drawImage(img, 0, 0, width, height);
}
// 進(jìn)行最小壓縮
var ndata = canvas.toDataURL('image/jpeg', 0.1);
// console.log('壓縮前:' + initSize)
// console.log('壓縮后:' + ndata.length)
// console.log('壓縮率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%")
tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
return ndata;
}
/**
* 獲取formdata
*/
function getFormData () {
var isNeedShim = ~navigator.userAgent.indexOf('Android') && ~navigator.vendor.indexOf('Google') && !~navigator.userAgent.indexOf('Chrome') && navigator.userAgent.match(/AppleWebKit\/(\d+)/).pop() <= 534;
return isNeedShim ? new this.FormDataShim() : new FormData();
}
/**
* formdata 補丁, 給不支持formdata上傳blob的android機打補丁
* @constructor
*/
function FormDataShim () {
var o = this;
var parts = [];
var boundary = Array(21).join('-') + (+new Date() * (1e16 * Math.random())).toString(36);
var oldSend = XMLHttpRequest.prototype.send;
this.append = function (name, value, filename) {
parts.push('--' + boundary + '\r\nContent-Disposition: form-data; name="' + name + '"');
if (value instanceof Blob) {
parts.push('; filename="' + (filename || 'blob') + '"\r\nContent-Type: ' + value.type + '\r\n\r\n');
parts.push(value);
} else {
parts.push('\r\n\r\n' + value);
}
parts.push('\r\n');
};
XMLHttpRequest.prototype.send = function (val) {
var fr;
var data;
var oXHR = this;
if (val === o) {
parts.push('--' + boundary + '--\r\n');
data = this.getBlob(parts);
fr = new FileReader();
fr.onload = function () {
oldSend.call(oXHR, fr.result);
}
fr.onerror = function (err) {
throw err;
}
fr.readAsArrayBuffer(data);
this.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
XMLHttpRequest.prototype.send = oldSend;
} else {
oldSend.call(this, val);
}
}
}
/**
* 獲取blob對象的兼容性寫法
* @param buffer
* @param format
* @returns {*}
*/
function getBlob (buffer, format) {
try {
return new Blob(buffer, {type: format});
} catch (e) {
var bb = new (window.BlobBuilder || window.WebKitBlobBuilder || window.MSBlobBuilder)();
buffer.forEach(function (buf) {
bb.append(buf);
});
return bb.getBlob(format);
}
}
/**
* @param {string} img 圖片的base64
* @param {int} dir exif獲取的方向信息
* @param {function} next 回調(diào)方法,返回校正方向后的base64
*/
function getImgData (img, dir, next) {
var image = new Image();
image.onload = function () {
var degree = 0;
var drawWidth;
var drawHeight;
var width;
var height;
drawWidth = this.naturalWidth;
drawHeight = this.naturalHeight; // 以下改變一下圖片大小
var maxSide = Math.max(drawWidth, drawHeight);
if (maxSide > 1024) {
var minSide = Math.min(drawWidth, drawHeight);
minSide = minSide / maxSide * 1024;
maxSide = 1024;
if (drawWidth > drawHeight) {
drawWidth = maxSide;
drawHeight = minSide;
} else {
drawWidth = minSide;
drawHeight = maxSide;
}
}
var canvas = document.createElement('canvas');
canvas.width = width = drawWidth;
canvas.height = height = drawHeight;
var context = canvas.getContext('2d'); // 判斷圖片方向,重置canvas大小,確定旋轉(zhuǎn)角度,iphone默認(rèn)的是home鍵在右方的橫屏拍攝方式
switch (dir) {
// iphone橫屏拍攝,此時home鍵在左側(cè)
case 3:
degree = 180
drawWidth = -width
drawHeight = -height
break
// iphone豎屏拍攝,此時home鍵在下方(正常拿手機的方向)
case 6:
canvas.width = height
canvas.height = width
degree = 90
drawWidth = width
drawHeight = -height
break
// iphone豎屏拍攝,此時home鍵在上方
case 8:
canvas.width = height
canvas.height = width
degree = 270
drawWidth = -width
drawHeight = height
break
}
// 使用canvas旋轉(zhuǎn)校正
context.rotate(degree * Math.PI / 180)
context.drawImage(this, 0, 0, drawWidth, drawHeight)
// 返回校正圖片
next(canvas.toDataURL('image/jpeg', 0.8))
}
image.src = img
}
如果是微信端,建議調(diào)用微信的拍照上傳,權(quán)限更多些!
希望對您有所幫助!
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機構(gòu),是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
北大課工場是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國制造2025”,實現(xiàn)中華民族偉大復(fù)興的升級產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項目經(jīng)理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺面向?qū)ο箝_發(fā)經(jīng)驗,技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點難點突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。