Repository navigation
CameraPreview not working correctly on Android devices with natural landscape orientation #149177
Copy link
Copy link
Closed
flutter/packages
#7044Labels
P1High-priority issues at the top of the work listHigh-priority issues at the top of the work liste: device-specificOnly manifests on certain devicesOnly manifests on certain devicesp: cameraThe camera pluginThe camera pluginpackageflutter/packages repository. See also p: labels.flutter/packages repository. See also p: labels.platform-androidAndroid applications specificallyAndroid applications specificallyr: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer versionteam-androidOwned by Android platform teamOwned by Android platform team
Description
What package does this bug report belong to?
camera
What target platforms are you seeing this bug on?
Android
Have you already upgraded your packages?
Yes
Dependency versions
pubspec.lock
[Paste file content here]
Steps to reproduce
- On Android devices with a natural landscape orientation, such as Docomo arrows Tab F-02K, run the following sample code
Expected results
CameraPreview shows the image naturally (the ground of the image faces downwards) regardless of the device orientation
Actual results
CameraPreview shows the image with incorrect orientation in all device orientations
Code sample
Code sample
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late CameraController _controller;
late Future<void> _initializeControllerFuture;
@override
void initState() {
super.initState();
_initializeControllerFuture = Future(() async {
final cameras = await availableCameras();
_controller = CameraController(cameras[0], ResolutionPreset.max);
await _controller.initialize();
setState(() {});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 300,
height: 300,
child: _controller.buildPreview(),
),
const Text("buildPreview()"),
],
),
Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 300,
height: 300,
child: CameraPreview(
_controller,
),
),
const Text("CameraPreview"),
],
),
],
),
);
} else {
return const Center(child: CircularProgressIndicator());
}
},
),
);
}
}
Screenshots or Videos
Screenshots / Video demonstration
Screen_recording_20240528_223632.mp4
Logs
Logs
[Paste your logs here]Flutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.16.9, on macOS 14.4.1 23E224 darwin-arm64, locale ja-JP)
• Flutter version 3.16.9 on channel stable at /Users/hykwy/development/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 41456452f2 (4 months ago), 2024-01-25 10:06:23 -0800
• Engine revision f40e976bed
• Dart version 3.2.6
• DevTools version 2.28.5
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
• Android SDK at /Users/hykwy/Library/Android/sdk
• Platform android-34, build-tools 34.0.0
• Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11572160)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 15.3)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 15E204a
• CocoaPods version 1.15.2
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2023.3)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11572160)
[✓] VS Code (version 1.88.1)
• VS Code at /Users/hykwy/Downloads/Visual Studio Code.app/Contents
• Flutter extension can be installed from:
🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[✓] Connected device (3 available)
• F 02K (mobile) • cc12da58 • android-arm64 • Android 9 (API 28)
• macOS (desktop) • macos • darwin-arm64 • macOS 14.4.1 23E224 darwin-arm64
• Chrome (web) • chrome • web-javascript • Google Chrome 125.0.6422.77
! Error: Browsing on the local area network for 高級なルーズリーフ. Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac.
The device must be opted into Developer Mode to connect wirelessly. (code -27)
[✓] Network resources
• All expected network resources are available.
• No issues found!
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
P1High-priority issues at the top of the work listHigh-priority issues at the top of the work liste: device-specificOnly manifests on certain devicesOnly manifests on certain devicesp: cameraThe camera pluginThe camera pluginpackageflutter/packages repository. See also p: labels.flutter/packages repository. See also p: labels.platform-androidAndroid applications specificallyAndroid applications specificallyr: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer versionteam-androidOwned by Android platform teamOwned by Android platform team
Activity
darshankawar commentedon May 29, 2024
Thanks for the report. I think this seems to be specific to the device you mentioned or with devices that have natural orientation landscape, because I tried the same on S10 device which gave me correct
CameraPreviewas below:I'll keep the issue open and label for tracking as device specific.
camsim99 commentedon May 29, 2024
@organic-nailer Can you confirm the version of the camera plugin that you're using?
Either way, I assume this issue comes from CameraX (assuming version >=0.11.0 is used) not behaving in the way that the plugin expects when the device has a natural landscape orientation.
organic-nailer commentedon May 30, 2024
I tried the camera plugin version 0.10.6 and 0.11.0, and have confirmed that this issue occurs with both. I don't think this issue is specific to the new CameraX plugin.
organic-nailer commentedon May 30, 2024
Based on my research, my hypothesis is as follows:
CameraController.buildPreview(). This is achieved by placing a Texture using thetextureIdfound in the providedCameraDescription.https://github.com/flutter/packages/blob/910fabb4886b975f13e0f98f60714c95b81465ed/packages/camera/camera_android/lib/src/android_camera.dart#L537-L540
TextureViewof the Camera2 API outputs an image after correcting for sensor orientation. This orientation is correct when the device is in its natural position (typically with the camera at the top). Screen rotation is not considered.https://developer.android.com/media/camera/camera2/camera-preview#textureview
CameraPreviewwidget wraps the Texture in aRotatedBoxto support screen rotation. The rotation amount is calculated fromCameraController.value.deviceOrientation. This is where the problem lies.deviceOrientationonly provides information on whether the screen is portrait, landscape, or inverted. It assumes, implicitly, that portrait with the top side up is the natural orientation, giving it a rotation of 0 degrees.https://github.com/flutter/packages/blob/910fabb4886b975f13e0f98f60714c95b81465ed/packages/camera/camera/lib/src/camera_preview.dart#L64-L72
Display.getRotation(), but Flutter currently disregards this and does not offer a way to access it from Dart.https://github.com/flutter/packages/blob/910fabb4886b975f13e0f98f60714c95b81465ed/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/sensororientation/DeviceOrientationManager.java#L316-L327
To resolve this issue, I believe we need to pass the value obtained from
Display.getRotation()to Dart and use it to determine the rotation amount.reidbaker commentedon May 30, 2024
@organic-nailer Thank you for such a well researched comment and explaining where we made our mistake!
[camerax] Add fix for camera preview rotation on landscape-oriented d…
github-actions commentedon Jul 22, 2024
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.[camerax] Add fix for camera preview rotation on landscape-oriented d…
[camerax] Add fix for camera preview rotation on landscape-oriented d…