You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 11:54:19