Newer
Older
SmTIAS-Capture / lib / models / display_orientation.dart
import 'package:flutter/material.dart';

/// プレビューを「撮影者が見る向き」に整えるための向き設定(単一の真実).
///
/// スマホを画面が下向きになるようアタッチメントへ載せて撮影する運用のため,
/// 生のカメラ映像をそのまま表示すると上下・左右が反転している.
/// 本クラスはその補正方法を一元管理する.
///
/// 向きの補正は**入力が異なる2系統**に分かれており,本クラスが両者の値を
/// まとめて保持する(座標系・パイプラインの詳細は SPEC_04 参照):
///
/// - **ライブ系**:`camera` パッケージの `CameraPreview`
///   (プラグインが既にセンサ向きを適用済み)に対し,追加で X 反転(鏡像)+
///   Y 反転(上下)を行う. → [previewMatrix](`OrientedPreview` が使用)
/// - **スナップショット系**:生 YUV フレーム(センサ向き未適用)を native で
///   回転・ミラーして同じ最終向きにする.
///   → [snapshotRotationDegrees] / [snapshotMirror](`convertYuvToJpeg` に渡す)
///
/// 2系統は適用対象(入力空間)が異なるため幾何的には別変換だが,
/// 「下向き設置時の撮影者向き」という**1つの意図**を実現する組として束ねている.
/// 向きを変えたいときは定数 [attachmentDownward] の値のみを変更すればよい.
/// ただし2系統の整合は実機でしか保証できないため,変更後は必ず実機で表示一致を
/// 確認すること(SPEC_04 段階2).
@immutable
class DisplayOrientation {
  /// ライブ系で X 反転(鏡像)するか.
  final bool flipHorizontal;

  /// ライブ系で Y 反転(上下)するか.
  final bool flipVertical;

  /// スナップショット系(native)の回転角(度).
  final int snapshotRotationDegrees;

  /// スナップショット系(native)でミラーするか.
  final bool snapshotMirror;

  const DisplayOrientation({
    required this.flipHorizontal,
    required this.flipVertical,
    required this.snapshotRotationDegrees,
    required this.snapshotMirror,
  });

  /// 下向きアタッチメント設置時の向き設定(現行の確定値).
  ///
  /// この値を変えるとライブ・スナップショット両系統の向きが変わる.
  static const DisplayOrientation attachmentDownward = DisplayOrientation(
    flipHorizontal: true,
    flipVertical: true,
    snapshotRotationDegrees: 90,
    snapshotMirror: true,
  );

  /// ライブプレビューに適用する変換行列(`Transform` 用).
  ///
  /// X/Y の反転を対角成分の符号で表現する(縦横同一スケールで歪み防止).
  Matrix4 get previewMatrix => Matrix4.diagonal3Values(
    flipHorizontal ? -1.0 : 1.0,
    flipVertical ? -1.0 : 1.0,
    1.0,
  );
}