一般情况下是 是使用 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) }) });