私は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;
EXIF指向の完全なソリューションが既にある最新のJavaScriptライブラリJavaScript-Load-Imageをご覧ください。 auto-fixが含まれています。
画像のスケーリング(.scale()
メソッド)を使用して、画像をキャンバスに変換し、画像の向きを修正できます。
JavaScriptで画像の向きを修正する をご覧ください。
ここに別の興味深いライブラリがあります: react-exif-orientation-img
ここでは、ソリューションの適応@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;