移動端H5上傳圖片等比例壓縮及部分iOS手機圖片旋轉(zhuǎn)90度解決方案

注:1.此方法將上傳的圖片等比例壓縮或放大至500kb左右。

? ? ? ? 2.上傳非正照,如人臉照片,強制旋轉(zhuǎn)為正照。

? ? ? ? 3.iOS 13.3.1以上版本手機拍出來的照片,視覺上是正照,實際順時針旋轉(zhuǎn)了90度,通過判斷版本號,強制逆時針旋轉(zhuǎn)90度回正后再上傳。

1.在公共js,如common.js里封裝:

/*圖片旋轉(zhuǎn)處理*/

export?function?rotateImg(img,?direction,?canvas)?{

????var?min_step?=?0;

????var?max_step?=?3;

????if?(img?==?null)?return;

????var?height?=?img.height;

????var?width?=?img.width;

????var?step?=?2;

????if?(step?==?null)?{

????????step?=?min_step;

????}

????if?(direction?==?'right')?{

????????step++;

????????step?>?max_step?&&?(step?=?min_step);

? ? ?}?else?{

????????step--;

????????step?<?min_step?&&?(step?=?max_step);

? ? ?}

????var?degree?=?step?*?90?*?Math.PI?/?180;

????var?ctx?=?canvas.getContext('2d');

? ??//解決iOS版本13.3.1以上圖片旋轉(zhuǎn)問題

????var?str=?navigator.userAgent.toLowerCase();?

????var?ver=str.match(/cpu?iphone?os?(.*?)?like?mac?os/);???

????if((ver?&&?ver[1].replace(/_/g,".").slice(0,2)==13?&&?ver[1].replace(/_/g,".").slice(3,4)>3)?||?(????ver?&&?ver[1].replace(/_/g,".").slice(0,2)>=14)?){? ?

? ? ? ????step?=?0;????

????? }

????switch?(step)?{

????????case?0:

????????????canvas.width?=?width;

????????????canvas.height?=?height;

????????????ctx.drawImage(img,?0,?0);

????????????break;

????????case?1:

????????????canvas.width?=?height;

????????????canvas.height?=?width;

????????????ctx.rotate(degree);

????????????ctx.drawImage(img,?0,?-height);

????????????break;

????????case?2:

????????????canvas.width?=?width;

????????????canvas.height?=?height;

????????????ctx.rotate(degree);

????????????ctx.drawImage(img,?-width,?-height);

????????????break;

????????case?3:

????????????canvas.width?=?height;

????????????canvas.height?=?width;

????????????ctx.rotate(degree);

????????????ctx.drawImage(img,?-width,?0);

????????????break;

????}

}

/*base64轉(zhuǎn)blob*/

? export function dataURLtoBlob(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

? ? ? });

? }

2.組件中使用:

<template>

????<input type="file"?accept="image/*"? @change="uploadImg($event)">

??</template>

import?{?rotateImg,?dataURLtoBlob?}?from?"@/utils/common";

methods:?{

??????uploadImg(e)?{? ??

????????if?(!e.target.files.length)?{

??????????return

????????}

????????if?(e.target.files[0].type.indexOf('image')?<?0)?{

??????????Toast({

????????????message:?'請選擇圖片上傳',

????????????duration:?1500

??????????});

??????????return

????????}

????????let?img?=?new?Image();

????????let?_this?=?this;

????????_this.Orientation?=?'';

????????Exif.getData(e.target.files[0],?function?()?{

????????????_this.Orientation?=?Exif.getTag(this,?"Orientation");

????????});

????????let?canvas?=?document.createElement('canvas');

????????let?cxt?=?canvas.getContext('2d');

????????let?windowURL?=?window.URL?||?window.webkitURL;

????????img.src?=?windowURL.createObjectURL(e.target.files[0]);

????????_this.uploading?=?true;

? ??????//圖片縮放

????????img.onload?=?function?()?{

??????????let?width?=?1000;

??????????let?height?=?img.naturalHeight?/?(img.naturalWidth?/?1000);

??????????if?(img.naturalWidth?>?img.naturalHeight)?{

????????????width?=?img.naturalWidth?/?(img.naturalHeight?/?1000);

????????????height?=?1000;

??????????}?else?{

????????????width?=?1000;

????????????height?=?img.naturalHeight?/?(img.naturalWidth?/?1000);

??????????}

??????????canvas.width?=?width;

??????????canvas.height?=?height;

??????????cxt.drawImage(this,?0,?0,?width,?height);

? ? ? ? ? //圖片旋轉(zhuǎn)

??????????if?(_this.Orientation?!=?""?&&?_this.Orientation?!=?1)?{

??????????????switch?(_this.Orientation)?{

??????????????????case?6:?//需要順時針(向左)90度旋轉(zhuǎn)

??????????????????????_this.rotateImg(this,?"left",?canvas);

??????????????????????break;

??????????????????case?8:?//需要逆時針(向右)90度旋轉(zhuǎn)

??????????????????????_this.rotateImg(this,?"right",?canvas);

??????????????????????break;

??????????????????case?3:?//需要180度旋轉(zhuǎn)

??????????????????????_this.rotateImg(this,?"right2",?canvas);

??????????????????????break;

??????????????}

??????????}

??????????_this.Orientation?=?''

? ? ? ? ?//生成圖片

??????????_this.PhotoBase64?=?canvas.toDataURL('image/jpeg');?//轉(zhuǎn)base64

??????????let?fileObj?=?_this.dataURLtoBlob(_this.PhotoBase64);?//把壓縮的base64轉(zhuǎn)化為對象

? ????????let?formData?=?new?FormData();

? ? ? ? ? formData.append('file',?fileObj);

??????????uploadImage(formData).then(res?=>?{

? ??????????_this.uploading?=?false;

????????????Toast({

??????????????message:?'上傳成功',

??????????????duration:?1500

????????????});

??????????}).catch(e?=>?{

????????????_this.uploading?=?false;

????????????Toast({

??????????????message:?'上傳失敗',

??????????????duration:?1500

????????????});

??????????})

????????}

??????},

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

友情鏈接更多精彩內(nèi)容