赞
踩
开发时需要用到Camera 来进行视频图片截取, 因此来写一些这方面内容
在pubspec.yaml
文件中添加 camera
依赖, 这里推荐使用一个vscode 插件:
Pubspec Assist
: 可以很方便的管理dart 的包依赖dependencies:
flutter:
sdk: flutter
camera: ^0.5.7+4
找到目录 ios/Runner/Info.plis
, 添加
<key>NSCameraUsageDescription</key>
<string>Can I use the camera please?</string>
<key>NSMicrophoneUsageDescription</key>
<string>Can I use the mic please?</string>
将Android sdk 的最低版本 调到21 (或更高)
进入android/app/build.gradle
文件, 修改目标行为以下内容.
minSdkVersion 21
注意这里是android 的sdk最小版本, 与emulator最小版本不同, 所以确保自己的android emulator版本在27以上!
注意如果你使用官方的示例代码, 必须添加下面main()函数中的第一行,否则报错
下面是完整正确的示例代码
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: }
依赖与代码都搞定之后就可以来打开测试了
按住alt+WASD
移动
下面对上面示例的某些代码进行逐行的详细的讲解
下面这行代码表示了所有的camera , 为什么是个List呢?
想一想, 我们的手机有多少个camera?
前置的, 后置的, 等等, 我们一个手机可以有好多camera , 因此他是一个List
5: List<CameraDescription> cameras;
注意这个虽然是用来描述cameras 的, 但是并不是我们手机相机真正的实例化对象, 我们不能用它来操作相机
controller是真正的相机实例化对象, 我们可以用它来进行录制, 拍照等等
下面的代码中, cameras[0]一般代表手机后置摄像头, 用来拍景色用, 你可以把他改成cameras[1]这样子就是前置的了(你可以自己修改代码尝试一下)
initState()
中进行相机初始化
controller.value.isInitialized
变为falsecontroller.value.isInitialized
变为true, 并且渲染CameraApp Widget21: @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: }
下面代码用来销毁controller
34: void dispose() {
35: controller?.dispose();
36: super.dispose();
37: }
为什么要进行销毁?
为了避免出现内存泄漏, controller是类内部的实例化对象, 所以显示的进行销毁, 避免出现内存泄漏
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对象虽然CameraPreview 对象 被一个AspectRadio对象包裹, 但是注意
AspectRatio
的英文意思是 宽高比 , 所以其实它是一个布局对象(与Camera 依赖包无关), 因此它会控制CemeraPreview对象的宽高比CemeraPreview
对象才是真正的摄像头界面对象, 需要一个摄像头实例化对象(这里是controller
作为参数) ,因此CameraPreview(controller)建立一个摄像头界面显示在界面中Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。