Flutter Camera插件使用入门

文章目录

    • 0. 前言
    • 1. 安装
      • 1.1 iOS
      • 1.2 Android
    • 2. 测试项目
      • 2.1 示例代码
      • 2.2 演示结果
    • 3. 代码讲解
      • 3.1 cameras描述
      • 3.2 camera controller
      • 3.3 dispose销毁对象
      • 3.4 build 方法
      • 3.3 CameraPreview 对象

0. 前言

开发时需要用到Camera 来进行视频图片截取, 因此来写一些这方面内容

1. 安装

pubspec.yaml 文件中添加 camera 依赖, 这里推荐使用一个vscode 插件:

  • Pubspec Assist: 可以很方便的管理dart 的包依赖

Flutter Camera插件使用入门_第1张图片

dependencies:
  flutter:
    sdk: flutter
  camera: ^0.5.7+4

1.1 iOS

找到目录 ios/Runner/Info.plis, 添加

<key>NSCameraUsageDescriptionkey>
<string>Can I use the camera please?string>
<key>NSMicrophoneUsageDescriptionkey>
<string>Can I use the mic please?string>

1.2 Android

将Android sdk 的最低版本 调到21 (或更高)

进入android/app/build.gradle 文件, 修改目标行为以下内容.

minSdkVersion 21

注意这里是android 的sdk最小版本, 与emulator最小版本不同, 所以确保自己的android emulator版本在27以上!

Flutter Camera插件使用入门_第2张图片

2. 测试项目

注意如果你使用官方的示例代码, 必须添加下面main()函数中的第一行,否则报错

2.1 示例代码

下面是完整正确的示例代码

File: d:\study\Android\Flutter\cameraTest\cameratest\lib\main.dart
1: import 'dart:async';
2: import 'package:flutter/material.dart';
3: import 'package:camera/camera.dart';
4: 
5: List<CameraDescription> cameras;
6: 
7: Future<void> main() async {
8:   WidgetsFlutterBinding.ensureInitialized();
9:   cameras = await availableCameras();
10:   runApp(CameraApp());
11: }
12: 
13: class CameraApp extends StatefulWidget {
14:   @override
15:   _CameraAppState createState() => _CameraAppState();
16: }
17: 
18: class _CameraAppState extends State<CameraApp> {
19:   CameraController controller;
20: 
21:   @override
22:   void initState() {
23:     super.initState();
24:     controller = CameraController(cameras[0], ResolutionPreset.medium);
25:     controller.initialize().then((_) {
26:       if (!mounted) {
27:         return;
28:       }
29:       setState(() {});
30:     });
31:   }
32: 
33:   @override
34:   void dispose() {
35:     controller?.dispose();
36:     super.dispose();
37:   }
38: 
39:   @override
40:   Widget build(BuildContext context) {
41:     if (!controller.value.isInitialized) {
42:       return Container();
43:     }
44:     return AspectRatio(
45:         aspectRatio:
46:         controller.value.aspectRatio,
47:         child: CameraPreview(controller));
48:   }
49: }

2.2 演示结果

依赖与代码都搞定之后就可以来打开测试了
按住alt+WASD 移动
Flutter Camera插件使用入门_第3张图片

3. 代码讲解

下面对上面示例的某些代码进行逐行的详细的讲解

3.1 cameras描述

下面这行代码表示了所有的camera , 为什么是个List呢?
想一想, 我们的手机有多少个camera?
前置的, 后置的, 等等, 我们一个手机可以有好多camera , 因此他是一个List

5: List<CameraDescription> cameras;

注意这个虽然是用来描述cameras 的, 但是并不是我们手机相机真正的实例化对象, 我们不能用它来操作相机

3.2 camera controller

controller是真正的相机实例化对象, 我们可以用它来进行录制, 拍照等等
下面的代码中, cameras[0]一般代表手机后置摄像头, 用来拍景色用, 你可以把他改成cameras[1]这样子就是前置的了(你可以自己修改代码尝试一下)

  • initState()中进行相机初始化
    • 如果初始化失败了 就为未挂载状态(即 !mouted = true) ,那么就返回null值, 并且controller.value.isInitialized 变为false
    • 如果初始化成功, 那么controller.value.isInitialized变为true, 并且渲染CameraApp Widget
21:   @override
22:   void initState() {
23:     super.initState();
24:     controller = CameraController(cameras[0], ResolutionPreset.medium);
25:     controller.initialize().then((_) {
26:       if (!mounted) {
27:         return;
28:       }
29:       setState(() {});
30:     });
31:   }

3.3 dispose销毁对象

下面代码用来销毁controller

34:   void dispose() {
35:     controller?.dispose();
36:     super.dispose();
37:   }

为什么要进行销毁?

为了避免出现内存泄漏, controller是类内部的实例化对象, 所以显示的进行销毁, 避免出现内存泄漏

3.4 build 方法

39:   @override
40:   Widget build(BuildContext context) {
41:     if (!controller.value.isInitialized) {
42:       return Container();
43:     }
44:     return AspectRatio(
45:         aspectRatio:
46:         controller.value.aspectRatio,
47:         child: CameraPreview(controller));
48:   }

上面的代码中和上面所讲的相关

  • 如果初始化失败了 controller.value.isInitialized 为false, 就返回一个空白的Container(), 在用户看来就是空白的什么也没有
  • 如果初始化成功那么controller.value.isInitialized为true, 并且返回AspectRatio对象

3.3 CameraPreview 对象

虽然CameraPreview 对象 被一个AspectRadio对象包裹, 但是注意

  • AspectRatio 的英文意思是 宽高比 , 所以其实它是一个布局对象(与Camera 依赖包无关), 因此它会控制CemeraPreview对象的宽高比
  • CemeraPreview对象才是真正的摄像头界面对象, 需要一个摄像头实例化对象(这里是controller 作为参数) ,因此CameraPreview(controller)建立一个摄像头界面显示在界面中

你可能感兴趣的:(flutter)