web-dev-qa-db-ja.com

入力type = "file"での画像の回転

私はreact-firebase-file-uploaderを使用してアバターをfirebaseストレージにアップロードしています。ただし、Portrait Orientationの画像(具体的には、AndroidおよびIOSデバイスで撮影した画像をアップロードするときはいつでも-OrientationRotate 90 CWメタデータで)画像は90度回転します。

私はこれについて以前読んだことがあり、撮影されたこれらのスマートフォンの画像は常にLandscapeにあると信じていますが、向きは保存されています 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;
8
Darren

EXIF指向の完全なソリューションが既にある最新のJavaScriptライブラリJavaScript-Load-Imageをご覧ください。 auto-fixが含まれています。

画像のスケーリング(.scale()メソッド)を使用して、画像をキャンバスに変換し、画像の向きを修正できます。

JavaScriptで画像の向きを修正する をご覧ください。

ここに別の興味深いライブラリがあります: react-exif-orientation-img

4
Zakaria Acharki

ここでは、ソリューションの適応@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;
1
Olim Saidov