网站设计 英文,网站开发有哪几类,松江建设机械网站,视觉设计公司Flutter 学习之旅 之 flutter 在 Android 端进行简单的打开前后相机预览 / 拍照保存 目录
Flutter 学习之旅 之 flutter 在 Android 端进行简单的打开前后相机预览 / 拍照保存
一、简单介绍
二、简单介绍 camera
三、安装 camera
四、简单案例实现
五、关键代码 一、简单…Flutter 学习之旅 之 flutter 在 Android 端进行简单的打开前后相机预览 / 拍照保存 目录
Flutter 学习之旅 之 flutter 在 Android 端进行简单的打开前后相机预览 / 拍照保存
一、简单介绍
二、简单介绍 camera
三、安装 camera
四、简单案例实现
五、关键代码 一、简单介绍
Flutter 是一款开源的 UI 软件开发工具包由 Google 开发和维护。它允许开发者使用一套代码同时构建跨平台的应用程序包括移动设备iOS 和 Android、Web 和桌面平台Windows、macOS 和 Linux。
Flutter 使用 Dart 编程语言它可以将代码编译为 ARM 或 Intel 机器代码以及 JavaScript从而实现快速的性能。Flutter 提供了一个丰富的预置小部件库开发者可以根据自己的需求灵活地控制每个像素从而创建自定义的、适应性强的设计这些设计在任何屏幕上都能呈现出色的外观和感觉。 二、简单介绍 camera
网址camera | Flutter package
一个用于iOS、Android和Web的Flutter插件允许访问设备摄像头。 三、安装 camera
1、直接运行命令
使用 Flutterflutter pub add camera 使用 Flutter 安装权限管理插件flutter pub add permission_handler 使用 Flutter 安装图片保存插件flutter pub add permission_handler 2、或者在 pubspec.yaml 添加
dependencies:camera: ^0.11.1permission_handler: ^11.4.0saver_gallery: ^4.0.1 四、简单案例实现
1、这里使用 Android Studio 进行创建 Flutter 项目 2、创建一个 application 的 Flutter 项目 3、工程创建后如下 4、添加权限 uses-permission android:nameandroid.permission.CAMERA/uses-permission android:nameandroid.permission.READ_EXTERNAL_STORAGE/uses-permission android:nameandroid.permission.WRITE_EXTERNAL_STORAGE/ 5、编写代码实现打开相机预览拍照功能 6、连接设备运行项目简单效果如下 五、关键代码
import dart:async;
import dart:io;
import dart:typed_data;
import package:camera/camera.dart;
import package:flutter/material.dart;
import package:path_provider/path_provider.dart show getExternalStorageDirectory;
import package:path/path.dart as path show join;
import package:permission_handler/permission_handler.dart;// 应用入口点
Futurevoid main() async {// 确保 Flutter 的 WidgetsBinding 已初始化WidgetsFlutterBinding.ensureInitialized();// 请求存储权限await requestPermissions();// 获取设备上所有可用的摄像头列表final cameras await availableCameras();runApp(MaterialApp(theme: ThemeData.dark(), // 使用暗色主题home: TakePictureScreen(cameras: cameras), // 传入摄像头列表),);
}// 请求存储权限的函数
Futurevoid requestPermissions() async {// 检查存储权限的状态var status await Permission.storage.status;if (!status.isGranted) {// 如果权限未开启则请求权限await Permission.storage.request();}
}// TakePictureScreen 页面
class TakePictureScreen extends StatefulWidget {// 构造函数传入摄像头列表const TakePictureScreen({super.key, required this.cameras});final ListCameraDescription cameras;overrideTakePictureScreenState createState() TakePictureScreenState();
}// TakePictureScreen 的状态管理
class TakePictureScreenState extends StateTakePictureScreen {late CameraController _controller; // 摄像头控制器late Futurevoid _initializeControllerFuture; // 初始化摄像头的 Futureint _selectedCameraIndex 0; // 当前选中的摄像头索引overridevoid initState() {super.initState();// 初始化当前选中的摄像头_initializeCamera(widget.cameras[_selectedCameraIndex]);}// 初始化摄像头的函数void _initializeCamera(CameraDescription camera) {_controller CameraController(camera, // 摄像头描述ResolutionPreset.medium, // 设置分辨率);_initializeControllerFuture _controller.initialize(); // 初始化摄像头}// 切换摄像头的函数void _switchCamera() {setState(() {// 切换到下一个摄像头_selectedCameraIndex (_selectedCameraIndex 1) % widget.cameras.length;// 释放当前摄像头资源_controller.dispose();// 初始化新的摄像头_initializeCamera(widget.cameras[_selectedCameraIndex]);});}overridevoid dispose() {// 释放摄像头资源_controller.dispose();super.dispose();}overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text(Take a picture)), // 页面标题body: FutureBuildervoid(future: _initializeControllerFuture, // 监听摄像头初始化的 Futurebuilder: (context, snapshot) {if (snapshot.connectionState ConnectionState.done) {// 如果摄像头初始化完成显示摄像头预览return CameraPreview(_controller);} else {// 如果摄像头初始化未完成显示加载动画return const Center(child: CircularProgressIndicator());}},),floatingActionButton: Column(mainAxisAlignment: MainAxisAlignment.end,children: [// 拍照按钮FloatingActionButton(onPressed: () async {try {await _initializeControllerFuture; // 确保摄像头已初始化final image await _controller.takePicture(); // 拍照print(Image path: ${image.path});// 读取图片文件为字节数据final file File(image.path);final imageBytes await file.readAsBytes();print(Image bytes length: ${imageBytes.length});// 手动保存图片到指定路径final saveResult await saveImageManually(imageBytes);ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(saveResult)),);} catch (e) {print(Error taking picture: $e);}},child: const Icon(Icons.camera_alt), // 拍照图标),const SizedBox(height: 16),// 切换摄像头按钮FloatingActionButton(onPressed: _switchCamera, // 切换摄像头child: const Icon(Icons.switch_camera), // 切换摄像头图标),],),);}
}// 手动保存图片到指定路径的函数
FutureString saveImageManually(Uint8List imageBytes) async {// 获取外部存储路径final directory await getExternalStorageDirectory();if (directory null) {throw Exception(Failed to get external storage directory.);}// 拼接目标路径final picturesDir path.join(directory.path, Pictures, CameraApp);// 确保目标目录存在await Directory(picturesDir).create(recursive: true);// 生成文件名final fileName camera_image_${DateTime.now().millisecondsSinceEpoch}.jpg;final filePath path.join(picturesDir, fileName);// 写入文件final file File(filePath);await file.writeAsBytes(imageBytes);print(Image saved manually to: $filePath);return Image saved to: $filePath;
} 代码说明 代码结构清晰每个函数和逻辑块都有详细的注释解释了其功能和实现方式。 关键点解释 如何初始化摄像头。 如何切换摄像头。 如何保存图片到指定路径。 错误处理在关键操作中添加了错误处理逻辑并打印了错误信息。 用户交互通过 SnackBar 提示用户图片保存成功或失败。