老铁记得 转发 ,猫哥会出现更多 Flutter 好文~~~~

微信群 ducafecat

b 站 https://space.bilibili.com/40...

原文

https://medium.com/geekcultur...

代码

https://github.com/jagrut-18/...

参考

  • https://pub.dev/packages/camera

注释

在许多应用程序中,咱们须要用户通过点击图片上传图片。为此,咱们能够应用设施的默认摄像头应用程序,但如果咱们须要集成一个应用程序内的摄像头呢?那么,这也是可能的 Flutter 。小组曾经开发了一个叫做摄像头的 https://pub.dev/packages/camera ,它能够让咱们做到这一点。

建设我的项目

首先,通过在 pubspec.yaml 文件中增加以下行,将 camera 包装置到我的项目中。

camera: ^0.8.1+3
  • IOS 设置

这个插件须要 IOS 10.0 或更高版本。在 Info.plist 文件中增加以下行来设置内容。

<key>NSCameraUsageDescription</key><string>Can I use the camera please?</string><key>NSMicrophoneUsageDescription</key><string>Can I use the mic please?</string>
  • Android Setup

在 Android/app/build.gradle 文件中将 Android sdk 最小版本更改为 21(或更高版本)。

minSdkVersion 21

当初咱们的我的项目设置实现了,咱们能够开始编写应用程序了。

咱们将在应用程序中创立两个屏幕。

1.CameraScreen ー此屏幕将显示相机输入并拍摄图片

2.GalleryScreen ー这个屏幕将在网格视图中显示捕捉的图片。

装载摄像头

为了显示相机预览,咱们须要首先加载相机。为此,转到 main.dart 文件中的 main 函数和 runApp 下面的这些行。

WidgetsFlutterBinding.ensureInitialized(); //Ensure plugin services are initializedfinal cameras = await availableCameras(); //Get list of available cameras

当初咱们有了相机列表,咱们须要把它们传递给咱们的相机/屏幕。

所以,摄像机会像这样通过

通过这所有之后,这就是 main.dart 的样子。

import 'package:camera/camera.dart';import 'package:flutter/material.dart';import 'camera_screen.dart';void main() async {  WidgetsFlutterBinding.ensureInitialized();  // Obtain a list of the available cameras on the device.  final cameras = await availableCameras();  runApp(MyApp(cameras: cameras));}class MyApp extends StatelessWidget {  final List<CameraDescription> cameras;  const MyApp({Key? key, required this.cameras}) : super(key: key);  @override  Widget build(BuildContext context) {    return MaterialApp(      title: 'Camera App',      home: CameraScreen(cameras: cameras),    );  }}

CameraScreen

这个屏幕的布局很简略。在顶部咱们将显示实时相机预览和在底部将有三个按钮(替换相机,捕捉和显示画廊)。

创立一个有状态小部件 CameraScreen。

咱们将创立四个变量,

咱们必须设置 selectedCamera = 0,从后置摄像头开始。如果设施有多于 1 个摄像头,咱们能够通过更改这个索引切换到它。

当初让咱们创立一个办法来初始化选定的相机。

在此办法中,咱们将传递要初始化的摄像机索引。应用通过的摄像机列表,咱们将加载具体的相机与分辨率的抉择。

应用这个办法,咱们将初始化 initState 中的后置摄像头。

别忘了丢掉相机控制器。

  • 当初让咱们构建 UI。

为了显示 CameraPreview,咱们将应用以下代码。

FutureBuilder<void>(  future: _initializeControllerFuture,  builder: (context, snapshot) {    if (snapshot.connectionState == ConnectionState.done) {      // If the Future is complete, display the preview.      return CameraPreview(_controller);    } else {      // Otherwise, display a loading indicator.      return const Center(child: CircularProgressIndicator());    }  },),

好了,当初咱们要间断显示三个按钮。

开关/摄像头按钮

首先是开关摄像头图标按钮。点击这个按钮,摄像头应该在前后之间切换。

为此,咱们将应用雷同的 initializeCamera 办法,但这一次 cameraIndex 将是动静的。cameraIndex 后置摄像头为 0,前置摄像头为 1(如果有前置摄像头的话)。

在点击,咱们将查看设施是否有多个摄像头,如果没有,咱们将显示一个带有音讯的 snackbar。

IconButton(  onPressed: () {    if (widget.cameras.length > 1) {      setState(() {        selectedCamera = selectedCamera == 0 ? 1 : 0;//Switch camera        initializeCamera(selectedCamera);      });    } else {      ScaffoldMessenger.of(context).showSnackBar(SnackBar(        content: Text('No secondary camera found'),        duration: const Duration(seconds: 2),      ));    }  },  icon: Icon(Icons.switch_camera_rounded, color: Colors.white),),

捕获按钮

为了显示捕捉按钮,我应用了一个半径为 60 的简略红色圆圈。点击后,咱们将应用相机控制器拍摄一张照片并将其增加到 captureImages 数组中。

GestureDetector(  onTap: () async {    await _initializeControllerFuture; //To make sure camera is initialized    var xFile = await _controller.takePicture();    setState(() {      capturedImages.add(File(xFile.path));    });  },  child: Container(    height: 60,    width: 60,    decoration: BoxDecoration(      shape: BoxShape.circle,      color: Colors.white,    ),  ),),

显示画廊按钮

这个按钮非常简单,咱们将显示从 capturedmages 数组拍摄的最初一张图片,当单击时,它将导航到 GalleryScreen。

GestureDetector(  onTap: () {    if (capturedImages.isEmpty) return; //Return if no image      Navigator.push(context,        MaterialPageRoute(          builder: (context) => GalleryScreen(            images: capturedImages.reversed.toList())));  },  child: Container(    height: 60,    width: 60,    decoration: BoxDecoration(      border: Border.all(color: Colors.white),      image: capturedImages.isNotEmpty      ? DecorationImage(image: FileImage(capturedImages.last), fit: BoxFit.cover)      : null,    ),  ),),

如您所见,GalleryScreen 承受捕捉的图像列表,因而咱们能够在 gridview 中显示它们。让咱们实现这一部分来看看应用程序的运行状况。

GalleryScreen

这是十分间接的屏幕。获取图像列表并在 GridView 中显示它们。

import 'dart:io';import 'package:flutter/material.dart';class GalleryScreen extends StatelessWidget {  final List<File> images;  const GalleryScreen({Key? key, required this.images}) : super(key: key);  @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: Text('Gallery'),      ),      body: GridView.count(        crossAxisCount: 3,        mainAxisSpacing: 2,        crossAxisSpacing: 2,        children: images            .map((image) => Image.file(image, fit: BoxFit.cover))            .toList(),      ),    );  }}

Final Product

在构建应用程序之后,这是最终的后果。

摄像头包也能够捕获视频,你能够应用 startVideoRecording,pauseVideoRecording 和 stopVideoRecording 办法来捕获 https://pub.dev/packages/Camera。

这是这个我的项目的 Github 链接,心愿对你有所帮忙。

https://github.com/jagrut-18/...

这个就到此为止,心愿你喜爱。


© 猫哥

https://ducafecat.tech/

https://github.com/ducafecat

往期

开源

GetX Quick Start

https://github.com/ducafecat/...

新闻客户端

https://github.com/ducafecat/...

strapi 手册译文

https://getstrapi.cn

微信探讨群 ducafecat

系列汇合

译文

https://ducafecat.tech/catego...

开源我的项目

https://ducafecat.tech/catego...

Dart 编程语言根底

https://space.bilibili.com/40...

Flutter 零根底入门

https://space.bilibili.com/40...

Flutter 实战从零开始 新闻客户端

https://space.bilibili.com/40...

Flutter 组件开发

https://space.bilibili.com/40...

Flutter Bloc

https://space.bilibili.com/40...

Flutter Getx4

https://space.bilibili.com/40...

Docker Yapi

https://space.bilibili.com/40...