代码之家  ›  专栏  ›  技术社区  ›  Darren

输入type=“file”时的图像旋转

  •  7
  • Darren  · 技术社区  · 6 年前

    我在用 react-firebase-file-uploader 将虚拟形象上传到firebase存储器。但是,任何时候我上传一个纵向图像(特别是 Android和iOS 设备-他们倾向于 方向顺时针旋转90 在他们的元数据中)图像旋转90度。

    我以前读过这篇文章,我相信这些拍摄的智能手机图像总是在 风景 但是方位是存储的 exif元 . 如果我错了,请纠正我?

    下面是使用react上载图像的组件的示例- firebase文件上传程序 -我知道这个包没有问题,这个问题的解决方案可能适用于许多应用程序。

    那么,我需要做什么来阅读 EXIF方向 ,更改旋转(如果需要,或者是我需要在上传文件时传递meta?)继续上传?

    class ProfilePage extends Component {
      state = {
        avatar: "",
        isUploading: false,
        progress: 0,
        avatarURL: ""
      };
    
      handleProgress = progress => this.setState({ progress });
      handleUploadError = error => {
        this.setState({ isUploading: false });
        console.error(error);
      };
      handleUploadSuccess = filename => {
        this.setState({ avatar: filename, progress: 100, isUploading: false });
        firebase
          .storage()
          .ref("images")
          .child(filename)
          .getDownloadURL()
          .then(url => this.setState({ avatarURL: url }));
      };
    
      render() {
        return (
          <div>
            <form>
              {this.state.isUploading && <p>Progress: {this.state.progress}</p>}
              {this.state.avatarURL && <img src={this.state.avatarURL} />}
              <FileUploader
                accept="image/*"
                name="avatar"
                randomizeFilename
                storageRef={firebase.storage().ref("images")}
                onUploadStart={this.handleUploadStart}
                onUploadError={this.handleUploadError}
                onUploadSuccess={this.handleUploadSuccess}
                onProgress={this.handleProgress}
              />
            </form>
          </div>
        );
      }
    }
    
    export default ProfilePage;
    
    2 回复  |  直到 6 年前
        1
  •  4
  •   Zakaria Acharki    5 年前

    你应该看看现代的javascript库 JavaScript-Load-Image 已经有一个完整的exif方向解决方案包括 自动修复 是的。

    你可以使用图像缩放( .scale() 方法)将图像转换为画布并固定图像方向。

    看一看 Fix image orientation with Javascript .

    下面是另一个有趣的库: react-exif-orientation-img

        2
  •  1
  •   Olim Saidov    6 年前

    以下是根据您的需要对解决方案@German Plebani Menized进行的修改:

    import React, {Component} from "react";
    import FileUploader from "react-firebase-file-uploader";
    import exif from 'exif-js';
    
    function readFile(file) {
      return new Promise(resolve => {
        var reader = new FileReader();
        reader.onload = e => resolve(e.target.result);
        reader.readAsDataURL(file);
      });
    };
    
    function createImage(data) {
      return new Promise(resolve => {
        const img = document.createElement('img');
        img.onload = () => resolve(img);
        img.src = data;
      })
    }
    
    function rotate(type, img) {
      return new Promise(resolve => {
        const canvas = document.createElement('canvas');
    
        exif.getData(img, function () {
          var orientation = exif.getAllTags(this).Orientation;
    
          if ([5, 6, 7, 8].indexOf(orientation) > -1) {
            canvas.width = img.height;
            canvas.height = img.width;
          } else {
            canvas.width = img.width;
            canvas.height = img.height;
          }
    
          var ctx = canvas.getContext("2d");
    
          switch (orientation) {
            case 2:
              ctx.transform(-1, 0, 0, 1, img.width, 0);
              break;
            case 3:
              ctx.transform(-1, 0, 0, -1, img.width, img.height);
              break;
            case 4:
              ctx.transform(1, 0, 0, -1, 0, img.height);
              break;
            case 5:
              ctx.transform(0, 1, 1, 0, 0, 0);
              break;
            case 6:
              ctx.transform(0, 1, -1, 0, img.height, 0);
              break;
            case 7:
              ctx.transform(0, -1, -1, 0, img.height, img.width);
              break;
            case 8:
              ctx.transform(0, -1, 1, 0, 0, img.width);
              break;
            default:
              ctx.transform(1, 0, 0, 1, 0, 0);
          }
    
          ctx.drawImage(img, 0, 0, img.width, img.height);
          ctx.toBlob(resolve, type);
        });
      })
    }
    
    
    class OrientationAwareFirebaseImageUploader extends Component {
      handleChange = (event) => {
        event.target.files.forEach(
          file => readFile(file)
            .then(createImage)
            .then(rotate.bind(undefined, file.type))
            .then(blob => {
              blob.name = file.name;
              this.uploader.startUpload(blob);
            })
        );
      }
    
      render() {
        return (
          <FileUploader
            {...this.props}
            ref={ref => this.uploader = ref}
            onChange={this.handleChange}
            accept="image/*"
          />
        );
      }
    }
    
    export default OrientationAwareFirebaseImageUploader;