Commentはじめに皆さんこんにちは。Nativeのカメラ機能を使用するうえで、react-native-cameraというおそらく一番メジャーなカメラ機能のパッケージ(外部モジュール)を使用したのですが、静止画像の大きさを通常の縦長の形ではなくて正方形などの形で保存するということが、iOSでは簡単にできたのですが恐らくパッケージ自体のバグによりAndroidではうまくできませんでした。最終的に上下の余白をカットして正方形にクロップする処理を行うことで、正方形などの縦長以外の形で画像を保存することができました。(パッケージ自体が修正されるのが一番いいのですが、現時点では私が調べた限りではアプリ側での対応策としては画像をクロップするという方法しかみつかりませんでした・・。)オーバーレイの調整などいろいろと大変だったので最終的にうまく行った方法をサンプルコードとともに紹介します。cameraのバージョンはそれぞれ以下のものを使用しています。Cameraを使用する上で、iOSではプレビュー画面のViewのスタイルを単純に変更して正方形にすることで自動的にプレビュー画面と同じ画面の比率で画像を保存することができました。Androidでは(バージョンや機種によって多少挙動が異なる部分はあったのですが)プレビュー画面そのものを正方形に表示させることができなかったり、プレビュー画面を正方形に表示させることはできても、保存される画像自体は縦長のままで保存されてしまうという現象に悩まされました。Androidでは画像が保存される際に90度回転された方向で保存されてしまい、保存した画像をサーバー側やアプリ内で表示させる際に保存された通りの90度回転された横向きの状態で表示されてしまうという問題も発生しましたので、こちらの対策として画像を回転させて保存するという処理も併せて行う必要がありました。(ちなみに本記事とは関係はないのですが、iOSでは正しい方向で画像は保存されるのですが、画像に付与されるexif情報では「-90度に回転」という情報がiOSのみ含まれていました。Nativeでexif情報を削除する方法がわからなかったのでこちらに関しては画像サーバーにアップロードする段階で画像の方向を修正するという処理を行いました・・。)オーバーレイでプレビュー画面を正方形に表示iOSでは必要がないのですが、Androidではreact-native-cameraモジュールのプレビュー画面の大きさを調整できなかったので、オーバーレイを表示させることでプレビュー画面の上下部分を隠すことでプレビュー画面を正方形のように表示させました。(react-native-cameraのバージョンは1.8.0を使用していますが、バージョンによってはこの処理は必要なくプレビュー画面をViewのスタイルを変更することで大きさが変えられることもあるようですが、その場合でも保存される画像自体は縦向きになっていて、加工が必要なようです。)ここで正方形に加工する画像と、プレビュー画像を厳密に合わせるために以下のような形で上下に表示させるオーバーレイの高さを計算しました。注意点は、iOSとは異なり、Androidでは上部に表示させるステータスバーの高さの分を計算に入れる必要があるという点です。iOSではプレビュー画面のスタイルを変えることができるのでオーバーレイ自体を表示させる必要がそもそもないのですが、ここではオーバーレイの高さをiOS/Androidで調整することで正方形に加工する画像と、プレビュー画像を合わせるようにしています。ここでの計算でステータスバーの高さを取得するために、以下のようにStatusBarモジュールをインポートする必要があります。'react-native';表示するオーバーレイの高さoverlayHeightは正方形の場合は以下のようにして計算しています。2;オーバーレイをかぶせることでプレビューが正方形になりました画像を90度回転させる正方形の画像の上下の余白をカットする前に、横向きで保存されてしまっている画像を90度回転させる必要があったのですが、これを実現するためにreact-native-image-rotateというパッケージを使用しました。react-native-image-rotate下に上げたコードでは、右方向に90度画像を回転させて、rotatedUriというURIに画像が回転済みの保存されます。cache直下にReactNative_rotated_image_1090087420378345175.jpgのような形のファイル名で保存されることになります。回転が成功したときの処理。ReactNative_rotated_image_1090087420378345175.jpgのような形で回転済みの画像が保存される。},);サンプルコードでは、rotateImage()というメソッドで画像の回転を行っていますが、回転→クロップというような順番で非同期で処理を行う必要があるので、Promiseを使っています。回転の方向は常に同じ(常に-90度回転された状態で保存)で、かつ機種によっては正しい方向で保存される場合もあったので、「画像の横の長さ>画像の縦の長さ」の場合のみ回転の処理を行っています。画像の上下の余白を切り取る次に回転の処理を行ったあとに縦長で保存された画像の上下の余白を切り取る(クロップする)処理を行います。Native自体に含まれるモジュールを使用して該当の処理を行って正方形、または横向きなどの形に画像を加工することができます。ここでは画像にクロップ処理を行うことで1:1の比率の正方形に加工していますが、クロップする画像の高さとオフセットを調整することで任意の比率の画像に加工することができます。高さ300の大きさで画像を切り出すことができます。クロップが成功したときの処理。ReactNative_cropped_image_89995556232220742.jpgのような形でクロップ済みの画像が保存される。},);サンプルコードではcropImage()というメソッドで上下の余白を切り取る処理を行っています。サンプルでは画像にクロップ処理を行うことで1:1の比率の正方形に加工していますが、クロップする画像の高さとオフセットを調整することで任意の比率の画像に加工することができます。まとめreact-native-cameraを使う場合にiOSでは簡単にできる正方形での画像保存のために、Androidではこのようにいろいろと面倒な処理をする必要がありました。いずれはパッケージ自体が修正されるとは思いますが、それまでの間で正方形などの形で保存する場合がある時は、是非参考にしてみてください。本サンプルでは簡略化のために画像に関するこれらの変数を処理のたびに上書きしています。cache直下にReactNative_rotated_image_1090087420378345175.jpgのような形で回転済みの画像が保存される。ここでクロップする高さを指定。cache直下にReactNative_cropped_image_89995556232220742.jpgのような形でクロップ済みの画像が保存される。},});優秀な技術者と一緒に、好きな場所で働きませんか株式会社もばらぶでは、優秀で意欲に溢れる方を常に求めています。働く場所は自由、働く時間も柔軟に選択可能です。現在、以下の職種を募集中です。ご興味のある方は、リンク先をご参照下さい。採用情報プロジェクトマネージャー(リモート)ソフトウェアエンジニア(リモート)デザイナー(リモート)Subscriptionメールアドレスを記入して購読すれば、更新をメールで受信できます。ThemePacific。