camera: don't double-mirror front cam on Android

CameraX's Preview use case builds the SurfaceTexture transform
matrix with a horizontal mirror baked in for the front camera (so
the selfie preview reads naturally without consumer effort). Flutter
applies that matrix when sampling the texture. Adding our own
`Transform.flip(flipX: true)` on top double-mirrors — which on its
own would just un-mirror the selfie, but combined with CameraX's
counter-rotation when the device tilts, it makes the rotation appear
to *follow* the phone (i.e. tilt CW 90° → preview goes 90° more
CW). Removing the Flutter flip lets CameraX's matrix do the work on
its own.

iOS keeps the Flutter flip: AVCaptureConnection.isVideoMirrored on
the data output is `false` there (capture-time mirror would land
in the recorded MP4), so the preview-only mirror must live in the
widget tree.
This commit is contained in:
agra
2026-05-13 18:14:26 +03:00
parent f78dd4d846
commit 181fce6ab9

View File

@@ -1,3 +1,5 @@
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, TargetPlatform;
import 'package:flutter/widgets.dart';
import 'camera.dart' show UxCameraController, UxCameraLens, UxCameraValue;
@@ -35,7 +37,17 @@ class UxCameraPreview extends StatelessWidget {
if (turns != 0) {
child = RotatedBox(quarterTurns: turns, child: child);
}
if (value.description.lens == UxCameraLens.front) {
// iOS only: AVCaptureConnection.isVideoMirrored is `false` on
// the data output (capture stays raw), so Flutter mirrors the
// selfie preview here. On Android, CameraX's Preview use case
// builds a SurfaceTexture transform matrix that already
// mirrors the front cam — adding our own flip on top
// double-mirrors and, when the device tilts, makes CameraX's
// counter-rotation appear to double in the same direction as
// the phone tilt (because we're flipping the axis CameraX
// rotated around).
if (defaultTargetPlatform != TargetPlatform.android &&
value.description.lens == UxCameraLens.front) {
child = Transform.flip(flipX: true, child: child);
}
return child;