一般情況下是 是使用 Exif.js 來讀取圖像的元數據 orientation(方向)
但是這里使用了antd-mobile 的ImagePicker 組件, onChange 函數直接返回了orientation參數,所以不需要使用exif.js了
1. 獲取orientation參數和文件參數
onChange = (files, type) => { if(type === 'add'){ this.setState({ loading:true, orientation:files[0].orientation }) this.transformBase64(files[0].file) }else { this.setState({loading:true}) this._Upload(this.state.index,'') } }
2.轉換base64
//轉換base64 transformBase64 (file){ const self = this; const reader = new FileReader(); reader.readAsDataURL(file); /* eslint-disable func-names */ // 箭頭函數會改變this,所以這里不能用肩頭函數 reader.onloadend = function () { // this.result就是轉化后的結果 const result = this.result; // 將base64添加到圖片標簽上 const img = new Image(); img.src = result; img.onload = function () { // 獲取旋轉后的圖片 const data = self.getRotateImg(img,self.state.orientation); // 如果上傳接口不支持base64,則這里需要將base64轉為文檔流 const file = self.dataURLtoFile(data); // 調用接口,上傳圖片 self.transformFileToFormData(file) } }; }
3.將File append進 FormData
// 將File append進 FormData transformFileToFormData (file) { const formData = new FormData(); // 自定義formData中的內容 // type formData.append('type', file.type); // size formData.append('size', file.size || "image/jpeg"); // name formData.append('name', file.name); // lastModifiedDate formData.append('lastModifiedDate', file.lastModifiedDate); // append 文件 formData.append('file', file); // 上傳圖片 this.uploadImg(formData); }
4.獲取圖片返回地址
uploadImg = (formData) => { const xhr = new XMLHttpRequest(); // 進度監聽 // xhr.upload.addEventListener('progress', (e)=>{console.log(e.loaded / e.total)}, false); // 加載監聽 // xhr.addEventListener('load', ()=>{console.log("加載中");}, false); // 錯誤監聽 xhr.addEventListener('error', ()=>{ const step = this.state.index; this.setState({ modeling:false }); if(step === 1){ this.setState({ faced:[] }) }else if(step === 2){ this.setState({ lookUp:[] }) }else if(step === 3){ this.setState({ overLook:[] }) }else if(step === 4){ this.setState({ left:[] }) }else if(step === 5){ this.setState({ right:[] }) } Toast.fail('建模失敗', 1) }, false); xhr.onreadystatechange = () => { if (xhr.readyState === 4) { if(xhr.status === 200 ){ const result = JSON.parse(xhr.responseText); if (result.status === 10000) { this._Upload(this.state.index,`http:${result.url}`,result.filename) this.setState({ faced:[{ url:`http:${result.url}`, id:123 }] }) } else { const step = this.state.index; this.setState({ modeling:false }); if(step === 1){ this.setState({ faced:[] }) }else if(step === 2){ this.setState({ lookUp:[] }) }else if(step === 3){ this.setState({ overLook:[] }) }else if(step === 4){ this.setState({ left:[] }) }else if(step === 5){ this.setState({ right:[] }) } Toast.fail(result.message,1.5) } }else { const step = this.state.index; this.setState({ modeling:false }); if(step === 1){ this.setState({ faced:[] }) }else if(step === 2){ this.setState({ lookUp:[] }) }else if(step === 3){ this.setState({ overLook:[] }) }else if(step === 4){ this.setState({ left:[] }) }else if(step === 5){ this.setState({ right:[] }) } Toast.fail('建模失敗', 1) } } }; xhr.open('POST', '/api/file/file/upload' , true); xhr.send(formData); };
5.上傳圖片
_Upload = (status,src,filename) => { this.setState({ loading:true }) this.tag = 'faced_id_card' if(status === 1){ this.tag = "faced_id_card" }else if(status === 2){ this.tag = "back_id_card" } HttpUtils.postForm('/api/face/image/save', { tag:this.tag, scheme:'http:', category:2, filename }).then(res => { this.setState({ loading:false }) if (res.status === 10000) { if(src === ''){ Toast.info('刪除成功',1) if(status === 1 ){ this.setState({ haveAvatar:[] }) }else if(status === 2 ){ this.setState({ haveNationalEmblem:[] }) } }else { Toast.info('上傳成功',1) if(this.state.status === 1 ){ this.setState({ haveAvatar:[{ url:src, id:Number((Math.random()*10000).toFixed(0)) }], }) }else if(this.state.status === 2 ){ this.setState({ haveNationalEmblem:[{ url:src, id:Number((Math.random()*10000).toFixed(0)) }], }) } } } else { Toast.fail(res.message,1.5) } }).catch(err => { Toast.info('操作失敗',1.5) this.setState({ loading:false }); }) }
后續:
遇到的問題
IphoeXS / iphone 6S / iphone7 在未處理的情況下都是逆時針90度 獲取的Orientation為6
iphone XR / iphone 11 在未處理的情況下是正常的 獲取的Orientation 也是6
找到原因
解決辦法:
let userAgent= navigator.userAgent.toLowerCase(); let ios=userAgent.match(/cpu iphone os (.*?) like mac os/); let reg = /.*\..*/; //判斷是否有小數點
if(!ios){ //正常
}else{ let iosVersion = ios[1].replace(/_/g,"."); //獲取ios系統版本
if(Number(iosVersion.split('.')[0]) < 13){ //轉
}else {
if(Number(iosVersion.split('.')[0]) > 13){ //正常
}else { //等於13 判斷ios系統有無.
if(reg.test(iosVersion)){ if(Number(iosVersion.split('.')[1]) < 4){ //轉
}else { //正常
} }else { //轉
} } } }
附加:react 使用exif的辦法
yarn add exif-js
import {EXIF} from 'exif-js';
let self = this EXIF.getData(files[0].file, function() { //alert(EXIF.getTag(this, 'Orientation')); console.log("this",JSON.stringify(EXIF.getTag(this, 'Orientation'))) console.log('讓我康康or',EXIF.getTag(this, 'Orientation')) // return self.setState({ or2:JSON.stringify(this.exifdata) }) });