APICloud开发者进阶之路| JS利用H5的canvas操作微信浏览器上传图片方向旋转

268 阅读2分钟
项目背景:微信公众号,不想用微信JS-SDK 图片上传功能
发现部分机型,微信内置浏览器,vant-upload组件选取图片会发生旋转

解决方案:利用H5的canvas标签操作图片旋转
代码注释不全,大概逻辑就是 选图片 =》读取文件后 =》 判断图片方向 =》用画布重画图片并旋转 =》保存图片文件
代码:
<!DOCTYPE html><html>  <head>    <meta charset="utf-8">    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />    <title>图片处理canvas旋转方向</title>    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vant@2.9/lib/index.css" />    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>    <script src="https://cdn.jsdelivr.net/npm/vant@2.9/lib/vant.min.js"></script>    <script src="https://cdn.bootcdn.net/ajax/libs/exif-js/2.3.0/exif.js"></script>    <style type="text/css">    </style>  </head>  <body>    <div id="app">      <van-field required :border="false" name="uploader" label="照片">        <template #input>          <van-uploader v-model="fileList" :max-count="1" :after-read="afterRead"></van-uploader>        </template>      </van-field>    </div>  </body>  <script type="text/javascript">    new Vue({      el: '#app',      data() {        return {          fileList: []        }      },      methods: {        async afterRead(file) {          var _this = this; // vue对象          // file.status = 'uploading';          // file.message = '图片处理';          EXIF.getData(file.file, function() {            // 旋转方向 1:0° 3:180° 6:顺时针90° 8:逆时针90°            var Orientation = EXIF.getTag(this, "Orientation");            var imgName = this.name; // 原图片名称            var imgType = this.type; // 原图片类型            if (!this || !window.FileReader) return; // 看支持不支持FileReader            // 创建一个reader            var reader = new FileReader();            // 将图片2将转成 base64 格式            reader.readAsDataURL(this);            reader.onloadend = function() {              var img = new Image();              img.src = reader.result;              var width = img.width;              var height = img.height;              var canvas = document.createElement('canvas');              var ctx = canvas.getContext("2d");              switch (Number(Orientation)) {                case 3:                  canvas.width = width;                  canvas.height = height;                  ctx.rotate(Math.PI / 180 * 180);                  ctx.drawImage(img, 0, 0, img.width, img.height, -img.width, -img.height, img.width, img.height);                  break;                case 6:                  canvas.width = height;                  canvas.height = width;                  ctx.rotate(Math.PI / 180 * 90);                  ctx.drawImage(img, 0, 0, img.width, img.height, 0, -img.height, img.width, img.height);                  break;                case 8:                  canvas.width = height;                  canvas.height = width;                  ctx.rotate(Math.PI / 180 * -90);                  ctx.drawImage(img, 0, 0, img.width, img.height, -img.width, 0, img.width, img.height);                  break;                default:                  canvas.width = width;                  canvas.height = height;                  ctx.drawImage(img, 0, 0);                  break;              }              var fileBase64 = canvas.toDataURL(imgType);              var newFile = _this.dataURLtoFile(imgName, imgType, fileBase64)              file.content = fileBase64              file.file = newFile              file.status = 'done'            }          });        },        dataURLtoFile(imgName, imgType, dataurl) {          var arr = dataurl.split(","),            bstr = atob(arr[1]),            n = bstr.length,            u8arr = new Uint8Array(n);          while (n--) {            u8arr[n] = bstr.charCodeAt(n);          }          return new File([u8arr], imgName, {            type: imgType          });        },      }    })  </script></html>复制代码