antd-mobile 移动端使用input调用摄像头拍摄图片反显时图片旋转问题

需要实现的页面效果:

antd-mobile 移动端使用input调用摄像头拍摄图片反显时图片旋转问题_第1张图片

点击头像进行图片上传;再次点击可以修改

遇到的问题:上传图片反显到框里面 图片旋转

最终解决方案:

          
console.log(index, fs)} selectable={true} accept="image/gif,image/jpeg,image/jpg,image/png" disableDelete />
//js代码 onChange = (files, type, index) => { console.log(files, type, index); if (type == 'add') { this.setState({ files, }); var file=files[files.length - 1].file; const windowURL = window.URL || window.webkitURL;//实现预览 var u = navigator.userAgent; var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端 if(isiOS){ console.log('ios'); console.log(file.size/1024+'kb') const isLt400K = file.size /1024 < 200; if(!isLt400K){ return this.getsmallpic(file) }else{ this.setState({ imgArr:files[files.length - 1].file, imgSrc:files[files.length - 1].url }) } }else if(isAndroid){ console.log('Android'); var that=this; this.rotateImg(files[files.length - 1].file).then(blob => { document.getElementById('imgBox').src = URL.createObjectURL(blob) // 转换后的img this.blobToDataURL(blob, function(dataurl) { console.log(file.size/1024+'kb') const isLt400K = file.size /1024 < 200; if(!isLt400K){ return that.getsmallpic(that.dataURLtoFile(dataurl,file.name)) }else{ this.setState({ imgArr:files[files.length - 1].file }) } }); }); }else{ console.log('pc') console.log(file.size/1024+'kb') const isLt400K = file.size /1024 < 200; if(!isLt400K){ return this.getsmallpic(file) }else{ this.setState({ imgArr:files[files.length - 1].file, imgSrc:files[files.length - 1].url }) } } } } blobToDataURL(blob, callback) { var a = new FileReader(); a.onload = function(e) { callback(e.target.result); } a.readAsDataURL(blob); return a; } //图片翻转 rotateImg(file) { return new Promise((resolve, reject) => { let img = new Image(); img.src = window.URL.createObjectURL(file); img.onload = () => { util.addScript('https://cdn.jsdelivr.net/npm/exif-js', () => { var EXIF=window.EXIF; // 获取图片源数据 上面已经引入EXIF全局变量 EXIF.getData(img, function () { // 获取图片orientation值 console.log(EXIF.getAllTags(this)) let orientation = EXIF.getTag(this, "Orientation"); let canvas = document.createElement("canvas"); let ctx = canvas.getContext("2d"); switch (orientation) { case 3: // 旋转180° canvas.width = img.width; canvas.height = img.height; ctx.rotate((180 * Math.PI) / 180); ctx.drawImage(img, -img.width, -img.height, img.width, img.height); break; case 6: // 旋转90° canvas.width = img.height; canvas.height = img.width; ctx.rotate((90 * Math.PI) / 180); ctx.drawImage(img, 0, -img.height, img.width, img.height); break; case 8: // 旋转-90° canvas.width = img.height; canvas.height = img.width; ctx.rotate((-90 * Math.PI) / 180); ctx.drawImage(img, -img.width, 0, img.width, img.height); break; default: // 没有源信息的图片和正常的图片是不需要旋转的 canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0, img.width, img.height); break; } // 处理完返回 (这里返回都是被压缩的,根据实际情况更改正常的图片处理方式) canvas.toBlob(file => resolve(file), 'image/jpeg', 0.8) }) }); } }) } //图片压缩 dataURLtoFile(dataurl, filename) { 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 File([u8arr], filename, {type:mime}); } // 图片压缩 getsmallpic(file){ return new Promise((resolve,reject)=>{ //对图片进行压缩 const reader = new FileReader() const image = new Image() image.onload = (imageEvent) => { const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); const width = image.width * 0.5 const height = image.height * 0.5 canvas.width = width; canvas.height = height; context.clearRect(0, 0, width, height); context.drawImage(image, 0, 0, width, height); const dataUrl = canvas.toDataURL(file.type); const blobData = this.dataURLtoFile(dataUrl,file.name); if(blobData){ if(blobData.size /1024 < 400){ Object.assign(blobData,{uid:blobData.lastModified}); const windowURL = window.URL || window.webkitURL;//实现预览 resolve(blobData) this.setState({ imgSrc:windowURL.createObjectURL(blobData) }) this.setState({ imgArr:blobData }) }else{ this.getsmallpic(blobData) } }else{ reject() } } reader.onload = (e => { image.src = e.target.result; }); reader.readAsDataURL(file); }) } //css片段 .fileStyle{ position: relative; display: block; width: 160px; height: 160px; border-radius: 50%; text-align: center; background: #f5f5f5; margin: 0 auto; border: 1px solid #0486FE; overflow: hidden; } .imgs { width: 160px !important; height: 160px !important; border-radius: 50%; position: relative; } .fileStyle input { position: absolute; left: 0; top: 0; z-index: 9; width: 160px; height: 160px; opacity: 0; } :global(.am-image-picker .am-image-picker-list .am-flexbox){ width: 165px !important; height: 165px !important; border-radius: 50%; position: absolute; top:0; left: 0; background-color: transparent!important; } :global(.am-image-picker-list){ padding: 0 0 0 0!important; margin-bottom: 0!important; } :global(.am-image-picker-upload-btn){ border-radius: 50% !important; border: 0 !important; } :global(.am-image-picker-list .am-image-picker-item .am-image-picker-item-content){ border-radius: 50% !important; border: 0 !important; } :global(.am-image-picker-list .am-image-picker-item){ opacity: 0!important; }

 

解题历程:

1.原始问题:刚开始使用input type类型为file上传文件 获取图片路径反显到img里面;遇到了几部手机会出现图片反显翻转的问题


                    



//js方法
    humanChange(e){
      const windowURL = window.URL || window.webkitURL;//实现预览
      const file = document.getElementById('faceHuman').files[0];
       console.log(file.size/1024+'kb')
       const isLt400K = file.size /1024 < 200;
       if(!isLt400K){
         return this.getsmallpic(file)  //压缩图片的方法
       }else{
         this.setState({
           imgSrc:windowURL.createObjectURL(file)
         })
        this.setState({
           imgArr:file
         })
       }
    }

//图片压缩的方法
    dataURLtoFile(dataurl, filename) {
        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 File([u8arr], filename, {type:mime});
      }
      // 图片压缩
       getsmallpic(file){
        return new Promise((resolve,reject)=>{
            //对图片进行压缩
            const reader = new FileReader()
            const image = new Image()
            image.onload = (imageEvent) => {
              const canvas = document.createElement('canvas');
              const context = canvas.getContext('2d');
              const width = image.width * 0.5
              const height = image.height * 0.5
              canvas.width = width;
              canvas.height = height;
              context.clearRect(0, 0, width, height);
              context.drawImage(image, 0, 0, width, height);
              const dataUrl = canvas.toDataURL(file.type);
              const blobData = this.dataURLtoFile(dataUrl,file.name);
              if(blobData){
                if(blobData.size /1024 < 400){
                  Object.assign(blobData,{uid:blobData.lastModified});
                    const windowURL = window.URL || window.webkitURL;//实现预览
                  resolve(blobData)
                  this.setState({
                    imgSrc:windowURL.createObjectURL(blobData),
                    class:1
                   }) 
                   this.setState({
                    imgArr:blobData
                })
                }else{
                  this.getsmallpic(blobData)
                }
                
              }else{
                reject()
              }
              
            }
            reader.onload = (e => { image.src = e.target.result; });
            reader.readAsDataURL(file);
        })
      }

反显到不同的手机上会出现不同的翻转情况;各种百度之后;找到了一个exif的插件;在方法上进行了修改

 2.第一次解决方法:(使用exif插件翻转处理图片)


                    



//js方法
    humanChange(e){
      const windowURL = window.URL || window.webkitURL;//实现预览
      const file = document.getElementById('faceHuman').files[0];
      this.rotateImg(file).then(blob => {
        document.getElementById('imgBox').src = URL.createObjectURL(blob) // 转换后的img
      })
      this.setState({
        imgArr:file
      })
    }

//图片旋转的方法&压缩
   rotateImg(file) {
    return new Promise((resolve, reject) => {
      let img = new Image();
      img.src = window.URL.createObjectURL(file);
      img.onload = () => {
        util.addScript('https://cdn.jsdelivr.net/npm/exif-js', () => {
          var EXIF=window.EXIF;
          // 获取图片源数据 上面已经引入EXIF全局变量
          EXIF.getData(img, function () {
            // 获取图片orientation值
            console.log(EXIF.getAllTags(this))
            let orientation = EXIF.getTag(this, "Orientation");
            let canvas = document.createElement("canvas");
            let ctx = canvas.getContext("2d");
            switch (orientation) {
              case 3: // 旋转180°
                canvas.width = img.width;
                canvas.height = img.height;
                ctx.rotate((180 * Math.PI) / 180);
                ctx.drawImage(img, -img.width, -img.height, img.width, img.height);
                break;
              case 6: // 旋转90°
                canvas.width = img.height;
                canvas.height = img.width;
                ctx.rotate((90 * Math.PI) / 180);
                ctx.drawImage(img, 0, -img.height, img.width, img.height);
                break;
              case 8: // 旋转-90°
                canvas.width = img.height;
                canvas.height = img.width;
                ctx.rotate((-90 * Math.PI) / 180);
                ctx.drawImage(img, -img.width, 0, img.width, img.height);
                break;
              default: // 没有源信息的图片和正常的图片是不需要旋转的
                canvas.width = img.width;
                canvas.height = img.height;
                ctx.drawImage(img, 0, 0, img.width, img.height);
                break;
            }
            // 处理完返回 (这里返回都是被压缩的,根据实际情况更改正常的图片处理方式)
            canvas.toBlob(file => resolve(file), 'image/jpeg', 0.8)
          })
        });
      }
    })
  }

结论:公司里除了一部苹果11的手机之外都展示正常 but 领导手机型号很巧的和这位同学型号一致 so~ 继续找方法

 

3.第二次解决方案:由于这个移动端基于ant-mobile框架写的 所以我决定使用一下这个里面的上传图片的组件

ImagePicker (由于组件上这个方法和实际使用中有点差别 所以原有的组件上进行了样式修改)
console.log(index, fs)} selectable={true} accept="image/gif,image/jpeg,image/jpg,image/png" disableDelete />
//js代码 onChange = (files, type, index) => { console.log(files, type, index); if (type == 'add') { this.setState({ files, }); this.rotateImg(files[files.length - 1].file).then(blob => { document.getElementById('imgBox').src = URL.createObjectURL(blob) // 转换后的img }) this.setState({ imgArr:files[files.length - 1].file }) } } //css代码 /*修改选择弹框的样式*/ :global(.am-image-picker .am-image-picker-list .am-flexbox){ width: 165px !important; height: 165px !important; border-radius: 50%; position: absolute; top:0; left: 0; background-color: transparent!important; } :global(.am-image-picker-list){ padding: 0 0 0 0!important; margin-bottom: 0!important; } :global(.am-image-picker-upload-btn){ border-radius: 50% !important; border: 0 !important; } :global(.am-image-picker-list .am-image-picker-item .am-image-picker-item-content){ border-radius: 50% !important; border: 0 !important; } :global(.am-image-picker-list .am-image-picker-item){ opacity: 0!important; }

结论:使用组件测试之后,得出结论:安卓手机直接使用这个组件会翻转;最后决定写个判断 如果是安卓手机 使用exif插件进行图片处理反显;如果是苹果手机原来得组件赋值。

4.第三次解决方案:(翻转完成后 可以适配)

             
console.log(index, fs)} selectable={true} accept="image/gif,image/jpeg,image/jpg,image/png" disableDelete />
//js代码 onChange = (files, type, index) => { console.log(files, type, index); if (type == 'add') { this.setState({ files, }); var u = navigator.userAgent; var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端 if(isiOS){ console.log('ios') this.setState({ imgArr:files[files.length - 1].file, imgSrc:files[files.length - 1].url }) }else if(isAndroid){ console.log('Android') this.rotateImg(files[files.length - 1].file).then(blob => { document.getElementById('imgBox').src = URL.createObjectURL(blob) // 转换后的img }) this.setState({ imgArr:files[files.length - 1].file }) }else{ console.log('pc') this.setState({ imgArr:files[files.length - 1].file, imgSrc:files[files.length - 1].url }) } } } //图片翻转&压缩 rotateImg(file) { return new Promise((resolve, reject) => { let img = new Image(); img.src = window.URL.createObjectURL(file); img.onload = () => { util.addScript('https://cdn.jsdelivr.net/npm/exif-js', () => { var EXIF=window.EXIF; // 获取图片源数据 上面已经引入EXIF全局变量 EXIF.getData(img, function () { // 获取图片orientation值 console.log(EXIF.getAllTags(this)) let orientation = EXIF.getTag(this, "Orientation"); let canvas = document.createElement("canvas"); let ctx = canvas.getContext("2d"); switch (orientation) { case 3: // 旋转180° canvas.width = img.width; canvas.height = img.height; ctx.rotate((180 * Math.PI) / 180); ctx.drawImage(img, -img.width, -img.height, img.width, img.height); break; case 6: // 旋转90° canvas.width = img.height; canvas.height = img.width; ctx.rotate((90 * Math.PI) / 180); ctx.drawImage(img, 0, -img.height, img.width, img.height); break; case 8: // 旋转-90° canvas.width = img.height; canvas.height = img.width; ctx.rotate((-90 * Math.PI) / 180); ctx.drawImage(img, -img.width, 0, img.width, img.height); break; default: // 没有源信息的图片和正常的图片是不需要旋转的 canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0, img.width, img.height); break; } // 处理完返回 (这里返回都是被压缩的,根据实际情况更改正常的图片处理方式) canvas.toBlob(file => resolve(file), 'image/jpeg', 0.8) }) }); } }) } //css片段 .fileStyle{ position: relative; display: block; width: 160px; height: 160px; border-radius: 50%; text-align: center; background: #f5f5f5; margin: 0 auto; border: 1px solid #0486FE; overflow: hidden; } .imgs { width: 160px !important; height: 160px !important; border-radius: 50%; position: relative; } .fileStyle input { position: absolute; left: 0; top: 0; z-index: 9; width: 160px; height: 160px; opacity: 0; } :global(.am-image-picker .am-image-picker-list .am-flexbox){ width: 165px !important; height: 165px !important; border-radius: 50%; position: absolute; top:0; left: 0; background-color: transparent!important; } :global(.am-image-picker-list){ padding: 0 0 0 0!important; margin-bottom: 0!important; } :global(.am-image-picker-upload-btn){ border-radius: 50% !important; border: 0 !important; } :global(.am-image-picker-list .am-image-picker-item .am-image-picker-item-content){ border-radius: 50% !important; border: 0 !important; } :global(.am-image-picker-list .am-image-picker-item){ opacity: 0!important; }

结论:图片上传到后台没有压缩 之后进行图片压缩处理

之后解决方法为最上面的解决方案

完美解决~

你可能感兴趣的:(antd-mobile 移动端使用input调用摄像头拍摄图片反显时图片旋转问题)