アプリ内で写真を撮りその画像を表示すると、写真の向きが上下逆さに表示されるという不具合を見つけました。

その際の解決法を紹介していきます。

起きた現象

↓↓「camera」というプラグインを使って、デバイスを横に90度回転して撮影します。
https://pub.dev/packages/camera

撮影した画像をアプリ内で表示すると、写真の向きが上下逆さに表示されていました。

手元のAndroidのPixel 7(OSバージョンはAndroid 13)でこの現象が起き、iPhone14Pro(iOSバージョンは16.5)では起きなかったです。

つまりOSや機種によって、起きたり起きなかったりするということで少し困りました?

原因

ほとんどの写真を保存する際は、Exifというファイルフォーマットで保存されます。

Wikipediaからの引用だとこのような感じです。

Exchangeable image file formatは、富士フイルムが開発し、当時の日本電子工業振興協会 で規格化された、写真用のメタデータを含む画像ファイルフォーマット。デジタルカメラの画像の保存に使われる。略称はExifで「エグジフ」。

つまり撮影した写真の他、写真の撮影日時や撮影した機種、ファイルサイズなど写真に関する情報も一緒に保存していますよ、ということです。

その中に撮影時のデバイスの回転情報も含みます。

この情報を元に、画像ビューアーは正しく画像を回転させ表示します。

しかし一部のデバイスでは、回転情報が正しく保存されないか、画像ビューアー側が正しく回転情報を解釈しない場合があるようです。

今回のケースでは、回転情報が正しく保存されていないことが原因で、画像が意図しない方向に回転していました。

正常に画像が表示されている時の、撮影時のデバイスの向きと正しい回転情報のペアはこちらでした。

- 回転なし: Rotated 90 CW
- 右に90度回転: Rotated 180
- 左に90度回転: Horizontal (normal)
- 上下反転: Rotated 90 CCW

しかし画像が回転して表示されるデバイスでは、以下のように回転情報が保存されていました。

- 回転なし: Rotated 90 CW
- 右に90度回転: Horizontal (normal) → ここが違う
- 左に90度回転: Rotated 180 → ここが違う
- 上下反転: Rotated 90 CCW

上記のように、デバイスを「右に90度回転」と「左に90度回転」して撮影した時に、正常に表示される画像の回転情報と異なっています。

これが画像が反転する原因でした。

解決方法

画像を表示する際に、回転情報が正しくない場合は、アプリ内で正しい向きに回転させるようにしました。

↓↓画像を回転させる際に使用したパッケージは、「flutter_image_compress」というものです。
https://pub.dev/packages/flutter_image_compress

コードは以下のような感じで、回転情報が正しくない場合は、rotateパラメータに180を代入して画像を反転させました。

// カメラを横向きに撮影し、回転情報が正しくない場合、rotateパラメータに180を代入
if (
    (nativeDeviceOrientation ==  NativeDeviceOrientation.landscapeRight && 
        data['Image Orientation'].toString() != 'Rotated 180') ||
    (nativeDeviceOrientation == NativeDeviceOrientation.landscapeLeft && 
        data['Image Orientation'].toString() != 'Horizontal (normal)')
) {
    orientation = 180;
}

// 画像を回転させる
final fixedImageBytes = await FlutterImageCompress.compressWithFile(
   file.path,
   rotate: orientation,
);

その後、その回転させた画像を画像表示する処理に渡して、無事正常な向きで表示されるようになりました?

まとめ

本記事のまとめは以下の通りです。

  • 画像が意図しない向きに回転するのは、Exifの回転情報が誤って保存されていたため。
  • 画像を表示する時、間違った回転情報の場合は反転処理して表示するようにした。

最後までお読みいただき、ありがとうございました。

参考文献