【问题标题】:Image rotation on input type="file"输入类型=“文件”上的图像旋转
【发布时间】:2018-12-27 02:19:09
【问题描述】:

我正在使用 react-firebase-file-uploader 将头像上传到 Firebase 存储。但是,任何时候我上传肖像方向的图像(特别是在 Android 和 IOS 设备上拍摄的图像 - 它们的元数据中往往有 OrientationRotate 90 CW)图像是旋转 90 度。

我之前已经阅读过这方面的内容,并且我相信这些智能手机拍摄的图像始终是横向,但方向是存储在EXIF 元中的。如有错误请指正?

以下是使用 react-firebase-file-uploader 上传图像的组件示例 - 我知道这不是这个包的问题,​​这个问题的解决方案可能适用跨许多应用程序。

那么,我需要做什么来读取 EXIF 方向,更改旋转(如果需要,或者我需要通过文件上传传递元数据?)并且仍然继续上传?

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;

【问题讨论】:

标签: javascript reactjs orientation exif


【解决方案1】:

您应该看看现代 javascript 库 JavaScript-Load-Image,它已经为 EXIF 方向提供了完整的解决方案,包括 auto-fix

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

看看Fix image orientation with Javascript

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

【讨论】:

    【解决方案2】:

    这里根据您的需要对 cme​​ts 中提到的解决方案 @German Plebani 进行了改编:

    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;
    

    【讨论】:

      猜你喜欢
      • 2021-03-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-20
      • 1970-01-01
      • 2018-09-03
      • 2012-04-02
      • 1970-01-01
      相关资源
      最近更新 更多