如何在Flutter中使用Camera包调用相机(不使用ImagePicker)
使用Camera包直接调用设备相机(无需ImagePicker)
步骤1:添加依赖
在pubspec.yaml中添加相机及权限处理依赖:
dependencies: flutter: sdk: flutter camera: ^0.10.5+5 # 建议使用最新版本 permission_handler: ^10.2.0 # 用于申请相机权限
执行flutter pub get完成依赖安装。
步骤2:配置平台权限
- Android:在
android/app/src/main/AndroidManifest.xml中添加相机权限声明:
<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />
- iOS:在
ios/Runner/Info.plist中添加权限说明:
<key>NSCameraUsageDescription</key> <string>需要访问相机拍摄照片</string>
步骤3:初始化相机控制器
先申请权限,再获取可用相机并初始化控制器:
import 'package:camera/camera.dart'; import 'package:permission_handler/permission_handler.dart'; late CameraController _controller; late Future<void> _initializeControllerFuture; Future<void> _initCamera() async { // 请求相机权限 var status = await Permission.camera.request(); if (!status.isGranted) { // 权限拒绝后的处理逻辑,比如提示用户开启权限 return; } // 获取设备可用相机列表 final cameras = await availableCameras(); // 选择后置相机(若后置不存在则选第一个相机) final targetCamera = cameras.firstWhere( (camera) => camera.lensDirection == CameraLensDirection.back, orElse: () => cameras[0], ); // 初始化相机控制器 _controller = CameraController( targetCamera, ResolutionPreset.medium, // 设置分辨率 enableAudio: false, // 不需要录音时设为false ); _initializeControllerFuture = _controller.initialize(); }
在页面初始化时调用该方法,比如在initState中:
@override void initState() { super.initState(); _initCamera(); }
步骤4:构建相机预览界面
使用CameraPreview组件展示实时相机画面:
@override Widget build(BuildContext context) { return Scaffold( body: FutureBuilder<void>( future: _initializeControllerFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { // 相机初始化完成,显示预览 return CameraPreview(_controller); } else { // 显示加载指示器 return const Center(child: CircularProgressIndicator()); } }, ), floatingActionButton: FloatingActionButton( onPressed: _takePicture, child: const Icon(Icons.camera), ), ); }
步骤5:拍摄并处理照片
实现拍摄逻辑,获取照片路径后可进行展示或保存:
Future<void> _takePicture() async { try { // 确保相机已完成初始化 await _initializeControllerFuture; // 拍摄照片,返回临时文件路径 final image = await _controller.takePicture(); // 跳转到照片展示页面(示例) if (!mounted) return; Navigator.push( context, MaterialPageRoute( builder: (context) => DisplayPictureScreen(imagePath: image.path), ), ); } catch (e) { // 捕获拍摄异常,可添加错误提示 print('拍摄失败:$e'); } } // 照片展示页面示例 class DisplayPictureScreen extends StatelessWidget { final String imagePath; const DisplayPictureScreen({super.key, required this.imagePath}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('拍摄的照片')), body: Image.file(File(imagePath)), ); } }
步骤6:释放相机资源
页面销毁时必须释放控制器,避免内存泄漏:
@override void dispose() { _controller.dispose(); super.dispose(); }
常见问题排查
- 相机初始化失败:检查权限配置是否正确,确认设备有可用相机硬件。
- 拍摄无响应:确保
_initializeControllerFuture完成后再调用takePicture。 - 分辨率适配问题:根据设备性能调整
ResolutionPreset,避免使用过高分辨率导致崩溃。
内容的提问来源于stack exchange,提问作者Parth Patel
相关产品推荐
相关产品推荐

