Flutter相机功能插件camera2的使用
Flutter相机功能插件camera2的使用
插件简介
camera 是一个用于访问设备摄像头的 Flutter 插件,支持 iOS、Android 和 Web 平台。通过该插件,您可以实现相机预览、拍照和录像等功能。
功能 | Android 支持情况 | iOS 支持情况 | Web 支持情况 |
---|---|---|---|
支持版本 | SDK 21+ | iOS 11.0+ | 详见 camera_web 文档 |
特性
- 在小部件中显示实时相机预览。
- 可以捕获快照并保存到文件。
- 支持视频录制。
- 可以通过 Dart 访问图像流。
安装
首先,在 pubspec.yaml
文件中添加 camera
作为依赖项:
dependencies:
camera: ^latest_version
然后运行以下命令以更新依赖项:
flutter pub get
iOS 配置
在 ios/Runner/Info.plist
中添加以下两行配置:
<key>NSCameraUsageDescription</key>
<string>您的相机使用描述</string>
<key>NSMicrophoneUsageDescription</key>
<string>您的麦克风使用描述</string>
Android 配置
在 android/app/build.gradle
文件中将最小 SDK 版本设置为 21 或更高:
minSdkVersion 21
注意:MediaRecorder
类在模拟器上可能无法正常工作。具体问题可参考官方文档:MediaRecorder。
Web 集成
对于 Web 平台的具体集成说明,请参考 camera_web 包的文档。
处理生命周期状态
从版本 0.5.0
开始,camera 插件不再自动处理生命周期变化。开发者需要手动控制相机资源。如果未正确处理,可能会导致意外行为(例如 issue #39109)。可以通过重写 didChangeAppLifecycleState
方法来实现:
[@override](/user/override)
void didChangeAppLifecycleState(AppLifecycleState state) {
final CameraController? cameraController = controller;
if (cameraController == null || !cameraController.value.isInitialized) {
return;
}
if (state == AppLifecycleState.inactive) {
cameraController.dispose();
} else if (state == AppLifecycleState.resumed) {
_initializeCameraController(cameraController.description);
}
}
处理相机访问权限
初始化相机控制器时可能会抛出权限错误,应妥善处理这些错误。以下是可能的错误类型及描述:
- CameraAccessDenied: 用户拒绝了相机访问权限。
- CameraAccessDeniedWithoutPrompt: iOS 用户之前已拒绝权限,无法再次提示。
- CameraAccessRestricted: iOS 设备上的相机访问被限制。
- AudioAccessDenied: 用户拒绝了音频访问权限。
- AudioAccessDeniedWithoutPrompt: iOS 用户之前已拒绝权限,无法再次提示。
- AudioAccessRestricted: iOS 设备上的音频访问被限制。
示例代码
以下是一个简单的示例,展示如何在 Flutter 应用中实现全屏相机预览。
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
late List<CameraDescription> _cameras;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
_cameras = await availableCameras();
runApp(const CameraApp());
}
/// CameraApp 是主应用类。
class CameraApp extends StatefulWidget {
/// 默认构造函数
const CameraApp({super.key});
[@override](/user/override)
State<CameraApp> createState() => _CameraAppState();
}
class _CameraAppState extends State<CameraApp> {
late CameraController controller;
[@override](/user/override)
void initState() {
super.initState();
controller = CameraController(_cameras[0], ResolutionPreset.max);
controller.initialize().then((_) {
if (!mounted) {
return;
}
setState(() {});
}).catchError((Object e) {
if (e is CameraException) {
switch (e.code) {
case 'CameraAccessDenied':
// 处理权限错误
break;
default:
// 处理其他错误
break;
}
}
});
}
[@override](/user/override)
void dispose() {
controller.dispose();
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
if (!controller.value.isInitialized) {
return Container();
}
return MaterialApp(
home: CameraPreview(controller),
);
}
}
更复杂的功能示例
以下是一个更复杂的示例,展示了如何实现相机的多种功能,如闪光灯模式切换、变焦控制等。
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
class CameraExampleHome extends StatefulWidget {
const CameraExampleHome({super.key});
[@override](/user/override)
State<CameraExampleHome> createState() => _CameraExampleHomeState();
}
// 其他代码省略...
更多关于Flutter相机功能插件camera2的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter相机功能插件camera2的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,camera
插件是用于访问设备相机功能的主要插件。虽然 camera2
是 Android 原生的相机 API,但在 Flutter 中,我们通常使用 camera
插件来访问相机功能,它内部可能会使用 camera2
API(在 Android 上)。
以下是如何在 Flutter 中使用 camera
插件的基本步骤:
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 camera
插件的依赖:
dependencies:
flutter:
sdk: flutter
camera: ^0.10.0+1
然后运行 flutter pub get
来安装依赖。
2. 配置 Android 和 iOS 项目
Android
在 android/app/src/main/AndroidManifest.xml
文件中添加相机权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
iOS
在 ios/Runner/Info.plist
文件中添加相机权限:
<key>NSCameraUsageDescription</key>
<string>We need access to your camera to take photos.</string>
<key>NSMicrophoneUsageDescription</key>
<string>We need access to your microphone to record videos.</string>
3. 初始化相机
在 Flutter 中初始化相机并显示预览:
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
class CameraApp extends StatefulWidget {
@override
_CameraAppState createState() => _CameraAppState();
}
class _CameraAppState extends State<CameraApp> {
CameraController? _controller;
List<CameraDescription>? cameras;
@override
void initState() {
super.initState();
_initializeCamera();
}
Future<void> _initializeCamera() async {
cameras = await availableCameras();
_controller = CameraController(
cameras![0], // 使用第一个摄像头
ResolutionPreset.medium,
);
await _controller!.initialize();
if (!mounted) return;
setState(() {});
}
@override
void dispose() {
_controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (_controller == null || !_controller!.value.isInitialized) {
return Container();
}
return Scaffold(
appBar: AppBar(title: Text('Camera Example')),
body: CameraPreview(_controller!),
floatingActionButton: FloatingActionButton(
onPressed: () async {
final image = await _controller!.takePicture();
print('Image saved to ${image.path}');
},
child: Icon(Icons.camera),
),
);
}
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MaterialApp(
home: CameraApp(),
));
}
4. 运行应用
现在你可以运行应用,并看到相机预览。点击浮动按钮可以拍照,照片的路径会打印到控制台。
5. 处理相机权限
在 Android 和 iOS 上,相机权限是必需的。你可以使用 permission_handler
插件来请求和管理权限。
dependencies:
permission_handler: ^10.0.0
然后在代码中请求权限:
import 'package:permission_handler/permission_handler.dart';
Future<void> _checkPermissions() async {
var status = await Permission.camera.status;
if (!status.isGranted) {
await Permission.camera.request();
}
}
在 initState
中调用 _checkPermissions
以确保应用有权限访问相机。
6. 处理不同摄像头
你可以通过 cameras
列表来切换不同的摄像头(例如前置和后置摄像头):
void _switchCamera() async {
if (cameras == null || cameras!.length < 2) return;
final newCamera = _controller!.description == cameras![0] ? cameras![1] : cameras![0];
_controller = CameraController(
newCamera,
ResolutionPreset.medium,
);
await _controller!.initialize();
if (!mounted) return;
setState(() {});
}
7. 录制视频
你还可以使用 camera
插件来录制视频:
Future<void> _startRecording() async {
if (!_controller!.value.isInitialized) {
return;
}
await _controller!.startVideoRecording();
}
Future<void> _stopRecording() async {
if (!_controller!.value.isRecordingVideo) {
return;
}
final video = await _controller!.stopVideoRecording();
print('Video saved to ${video.path}');
}