做H5頁面,調用相冊圖片文件太大,怎么實現(xiàn)上傳縮略圖或者壓縮圖
趁著中午,大致代碼的我寫一下,供參考:
// 上傳函數(shù)
function upload(e) {
var file = e.target.files[0];
if (!file) return; // 未上傳
var orientation; // 圖片上傳的角度,解決
/**
* 利用exif.js解決ios手機上傳豎拍照片旋轉90度問題
* 詳見 http://code.ciaoca.com/javascript/exif-js/
*/
EXIF.getData(file, function () { // 獲取照片方向角屬性,用戶旋轉控制
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); // 調用上傳接口函數(shù)
img = null;
return;
}
// 圖片加載完畢之后進行壓縮,然后上傳
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的圖片轉成二進制對象,塞進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對大圖片進行壓縮
* @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);
}
// 進行最小壓縮
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 回調方法,返回校正方向后的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大小,確定旋轉角度,iphone默認的是home鍵在右方的橫屏拍攝方式
switch (dir) {
// iphone橫屏拍攝,此時home鍵在左側
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旋轉校正
context.rotate(degree * Math.PI / 180)
context.drawImage(this, 0, 0, drawWidth, drawHeight)
// 返回校正圖片
next(canvas.toDataURL('image/jpeg', 0.8))
}
image.src = img
}
如果是微信端,建議調用微信的拍照上傳,權限更多些!
希望對您有所幫助!
北大青鳥APTECH成立于1999年。依托北京大學優(yōu)質雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
北大青鳥中博軟件學院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網學院和江蘇省首批服務外包人才培訓基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團創(chuàng)建于1999年,經過二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術與教育服務機構,發(fā)展為教育服務業(yè)的綜合性企業(yè)集團,成為集合面授教學培訓、網
達內教育集團成立于2002年,是一家由留學海歸創(chuàng)辦的高端職業(yè)教育培訓機構,是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
曾工作于聯(lián)想擔任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔任項目經理從事移動互聯(lián)網管理及研發(fā)工作,曾創(chuàng)辦藍懿科技有限責任公司從事總經理職務負責iOS教學及管理工作。
浪潮集團項目經理。精通Java與.NET 技術, 熟練的跨平臺面向對象開發(fā)經驗,技術功底深厚。 授課風格 授課風格清新自然、條理清晰、主次分明、重點難點突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網頁制作和網頁游戲開發(fā)。
具有10 年的Java 企業(yè)應用開發(fā)經驗。曾經歷任德國Software AG 技術顧問,美國Dachieve 系統(tǒng)架構師,美國AngelEngineers Inc. 系統(tǒng)架構師。