在Flutter中禁用旋转的情况下,以横向和纵向方式拍摄相机照片



我想构建一个允许我拍摄风景和肖像照片的屏幕。我的应用程序只运行在纵向模式通过调用以下main:

等待SystemChrome.setPreferredOrientations ([DeviceOrientation.portraitUp]);

由于我的屏幕不再旋转,所以即使我将手机倾斜到一边,图像也总是以纵向拍摄。下面是一个小的示例项目,您可以清楚地看到:

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:flutter/services.dart';
List<CameraDescription> cameras = [];
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
cameras = await availableCameras();
runApp(CameraApp());
}
class CameraApp extends StatefulWidget {
@override
_CameraAppState createState() => _CameraAppState();
}
class _CameraAppState extends State<CameraApp> {
CameraController? controller;
bool takingPicture = false;
XFile? selectedImage;
@override
void initState() {
super.initState();
controller = CameraController(cameras[0], ResolutionPreset.max);
controller!.initialize().then((_) {
if (!mounted) {
return;
}
setState(() {});
});
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (!controller!.value.isInitialized) {
return Container();
}
return MaterialApp(
home: Stack(
fit: StackFit.expand,
children: [
RotatedBox(
quarterTurns: 1 - controller!.description.sensorOrientation ~/ 90,
child: CameraPreview(controller!),
),
CameraPreview(controller!),
Align(
alignment: Alignment.bottomRight,
child: FloatingActionButton(
onPressed: () {
if (!takingPicture) {
takingPicture = true;
controller!.takePicture().then(
(value) {
selectedImage = value;
setState(() {});
takingPicture = false;
},
);
}
},
),
),
Align(
alignment: Alignment.bottomLeft,
child: selectedImage != null
? Container(
height: 100,
width: 200,
child: Image.file(
File(selectedImage!.path),
),
)
: Container(),
),
],
),
);
}
}

当旋转手机并拍照时,照片也应该出现在横向,但它没有。我如何在不取出setPreferredOrientations的情况下解决这个问题?

Android和iOS上的普通移动应用程序也可以这样做。

我要做的是在进入屏幕时删除约束,并在进入时重新应用它。

下面是一个改编自你的代码的例子,它有两个屏幕:

  • 无法旋转的欢迎屏幕
  • 旋转的摄像头屏幕
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:flutter/services.dart';
List<CameraDescription> cameras = [];
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
cameras = await availableCameras();
runApp(MaterialApp(home: WelcomeScreen()));
}
class WelcomeScreen extends StatelessWidget {
const WelcomeScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Welcome! Try rotating the screen, you won't be able to!'),
SizedBox(height: 10),
ElevatedButton(
onPressed: () => Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (_) => CameraApp()),
),
child: Text('Press me to go to the camera'),
),
],
),
),
);
}
}
class CameraApp extends StatefulWidget {
@override
_CameraAppState createState() => _CameraAppState();
}
class _CameraAppState extends State<CameraApp> {
CameraController? controller;
bool takingPicture = false;
XFile? selectedImage;
@override
void initState() {
super.initState();
// Remove the constraint when entering, this is ok
// not to away since the app is in portrait mode by
// default
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
controller = CameraController(cameras[0], ResolutionPreset.max);
controller!.initialize().then((_) {
if (!mounted) {
return;
}
setState(() {});
});
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (!controller!.value.isInitialized) {
return Container();
}
return MaterialApp(
home: Stack(
fit: StackFit.expand,
children: [
RotatedBox(
quarterTurns: 1 - controller!.description.sensorOrientation ~/ 90,
child: CameraPreview(controller!),
),
CameraPreview(controller!),
Align(
alignment: Alignment.bottomCenter,
child: ElevatedButton(
onPressed: () async {
// Restore the constraint before navigating away
// DO await here to avoid any other screen in
// landscape mode
await SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (_) => WelcomeScreen()),
);
},
child: Text('Press me to go Home'),
),
),
Align(
alignment: Alignment.bottomRight,
child: FloatingActionButton(
onPressed: () async {
if (!takingPicture) {
takingPicture = true;
controller!.takePicture().then(
(value) {
selectedImage = value;
setState(() {});
takingPicture = false;
},
);
}
},
),
),
Align(
alignment: Alignment.bottomLeft,
child: selectedImage != null
? Container(
height: 100,
width: 200,
child: Image.file(
File(selectedImage!.path),
),
)
: Container(),
),
],
),
);
}
}

最新更新