H5拍照

作者: cutecat | 来源:发表于2023-10-18 17:03 被阅读0次

<input
type="file"
accept="image/*"
@change="select">
iOS下会唤起选择照片或者拍照面板
Android直接进入选择照片,添加capture="camera"后直接唤起拍照
所以Android需要自己实现一个拍照或者选择照片面板来适应iOS,所以让APP实现去吧,整个统一的UI

    select(event) {
      // eslint-disable-next-line no-console
      console.log('select', event, event.target);
      const file = event.target.files[0];
      // eslint-disable-next-line no-console
      console.log('start', file);
      const fileReader = new FileReader();
      fileReader.onload = async (e) => {
        // eslint-disable-next-line no-console
        console.log('filereader.onload', file, file.type, e.target);
        const base64Str = e.target.result;
        if (!base64Str) {
          Toast.show('选择文件有误,请重试');
          return;
        }

        const img = new Image();
        img.onload = async () => {
          try {
            // eslint-disable-next-line no-console
            console.log('img.onload');
            // 获取横屏竖屏
            const Orientation = await this.getOrientation(img);
            let n = 0;
            if (Orientation === 6) {
              n = 1;
            }
            // iphone拍照上传图片横屏的问题
            const canvas = this.rotateAndCompressImg(img, n, 700);
            // eslint-disable-next-line no-console
            console.log('canvas压缩旋转后的canvas');
            // 导出base64文件
            const imgData = canvas.toDataURL('image/jpeg');
            // eslint-disable-next-line no-console
            console.log('canvas压缩旋转后的base64', imgData.length);
            // 获取被canvas压缩后的图片对象,从而获取base64字符串字节大小
            const blob = await Tools.base64ToBlob(imgData.split(',')[1], 'image/png');
            // eslint-disable-next-line no-console
            console.log('压缩后的img', blob, blob.size);
            // 限制 15M 以内
            if (blob.size > 1048576 * 15) {
              Toast.show('选择文件太大,请重选');
              return;
            }
            this.uploadImg({
              file: imgData.slice(imgData.indexOf(',') + 1),
              type: 'image/jpeg'
            });
            // change事件监听的是input的value的改变,不清空,就不能选择同一个文件
            // eslint-disable-next-line no-console
            console.log(event.target);
            if (event.target && event.target.value) {
              event.target.value = '';
            }
          } catch (err) {
            // eslint-disable-next-line no-console
            console.log('外层', err);
          }
        };
        img.src = base64Str;
      };
      fileReader.readAsDataURL(file);
    },
    getOrientation(img) {
      return new Promise(((resolve) => {
        EXIF.getData(img, function _cb() {
          try {
            EXIF.getAllTags(this);
            const Orientation = EXIF.getTag(this, 'Orientation');
            resolve(Orientation);
          } catch (e) {
            // eslint-disable-next-line no-console
            console.log('getOrientation', e);
            // reject(e);
            // 即便获取图片宽高失败也不阻止后续图片上传显示,只是不能旋转
            resolve(0);
          }
        });
      }));
    },
    rotateAndCompressImg(img, n, maxWidth = 700) {
      const canvas = document.createElement('canvas');
      const anw = document.createAttribute('width');
      const anh = document.createAttribute('height');
      let w;
      let h;
      const isLandscape = n % 2 !== 0;
      // eslint-disable-next-line no-console
      console.log('img原始宽高', img.width, img.height);
      if (isLandscape) {
        w = img.height;
        h = img.width;
      } else {
        w = img.width;
        h = img.height;
      }

      if (w > maxWidth) {
        h *= (maxWidth / w);
        w = maxWidth;
      }
      anw.nodeValue = w;
      anh.nodeValue = h;
      canvas.setAttributeNode(anw);
      canvas.setAttributeNode(anh);
      const ctx = canvas.getContext('2d');
      ctx.translate(w / 2, h / 2);
      ctx.rotate(n * 0.5 * Math.PI);
      ctx.drawImage(img, -w / 2, -h / 2, w, h);
      return canvas;
    },
    async uploadImg({ file, type }) {
      // eslint-disable-next-line no-console
      console.log('uploadImg');
      Indicator.open({
        text: '图片上传中...',
      });
      try {
        const { url: src } = await recruitApi.uploadImage({
          file: file || '',
          image: 40,
          type: this.getPlatform()
        });
        Indicator.close();
        this.urls.push({
          type,
          src
        });
      } catch (error) {
        if (error.name === 'CustomError') {
          Toast.show(error.response && error.response.data && error.response.data.msg);
          return;
        }
        Toast.show(error.message);
      } finally {
        Indicator.close();
      }
    },

相关文章

网友评论

      本文标题:H5拍照

      本文链接:https://www.haomeiwen.com/subject/wlzpbdtx.html