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