Flutter相机功能插件flutter_feature_camera的使用
Flutter相机功能插件flutter_feature_camera的使用
描述
一个Flutter库提供了与相机功能相关的各种方法、抽象类等,包括拍摄照片、管理闪光灯模式、在前后摄像头之间切换以及启用图像流。
开始使用
Android
android {
// ... 其他代码
defaultConfig {
minSdkVersion 21 // 将minSdkVersion改为21
}
}
关键特性
矩形覆盖层
一个自定义画笔,绘制一个半透明覆盖层,并在中心留出一个矩形的切口。通常用作相机覆盖层,以突出显示用于捕获身份证或文档的区域。
RectanglePainterV2
类在屏幕上绘制一个覆盖层,其中心有一个清晰的矩形,允许用户专注于矩形内的内容(例如,拍摄身份证照片)。
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("相机ID卡页面", style: TextStyle(color: Colors.black)),
),
body: Stack(
children: [
// 相机预览区域
Container(
alignment: Alignment.center,
child: cameraController?.value.isInitialized == true
? CameraPreview(cameraController!)
: Container(),
),
// ID卡捕捉的覆盖矩形
IgnorePointer(
child: CustomPaint(
painter: RectanglePainterV2(),
child: Container(),
),
),
],
),
);
}
圆形覆盖层
一个自定义画笔,绘制一个半透明覆盖层,并在中心留出一个圆形的切口和可选的进度弧。通常用作自拍相机的覆盖层,以便聚焦于屏幕中心的主体。
CirclePainterV2
类设计为在屏幕上绘制一个中心清晰的圆形覆盖层,适用于自拍相机应用或其他需要圆形覆盖层的用途。此外,它还支持在圆形周围绘制进度弧,这可以用于指示捕获进度。
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("相机ID卡页面", style: TextStyle(color: Colors.black)),
),
body: Stack(
children: [
// 相机预览区域
Container(
alignment: Alignment.center,
child: cameraController?.value.isInitialized == true
? CameraPreview(cameraController!)
: Container(),
),
// 自拍相机的覆盖圆形
IgnorePointer(
child: CustomPaint(
painter: CirclePainterV2(),
child: Container(),
),
),
],
),
);
}
基础相机
BaseMixinFeatureCameraV2
是一个混合类,旨在方便地处理与相机相关的功能。它提供了处理基本相机功能的方法,如初始化相机、拍照、切换摄像头、设置闪光灯模式、启动和停止图像流等。
此混合类可以在需要相机功能的小部件或类中使用,允许在Flutter应用程序中轻松集成相机操作。
class CustomCameraPage extends StatefulWidget {
const CustomCameraPage({super.key});
[@override](/user/override)
State<CustomCameraPage> createState() => _CustomCameraPageState();
}
class _CustomCameraPageState extends State<CustomCameraPage> with BaseMixinFeatureCameraV2 {
[@override](/user/override)
void initState() {
super.initState();
addListener(onFlashModeChanged: onFlashModeChanged);
initializeCamera(
cameraLensDirection: CameraLensDirection.back,
onCameraInitialized: onCameraInitialized,
onCameraInitializedFailure: (FeatureCameraException exception) {},
);
}
void onCameraInitialized(CameraController controller) {
setState(() {});
}
}
检查相机是否可用
检查具有指定 cameraLensDirection
的相机是否可用。
此函数在 BaseMixinFeatureCameraV2
中可用。
final isCameraAvailable = isCameraAvailable(CameraLensDirection.back);
参数名称 | 类型 | 必填 | 描述 |
---|---|---|---|
cameraLensDirection |
CameraLensDirection | 是 | 相机的方向。可能的值 (CameraLensDirection.back, CameraLensDirection.front, CameraLensDirection.external) |
切换相机镜头方向
将活动相机切换到指定的 CameraLensDirection
。
此函数在 BaseMixinFeatureCameraV2
中可用。
void screenFunction() {
switchCamera(CameraLensDirection.back);
}
参数名称 | 类型 | 必填 | 描述 |
---|---|---|---|
cameraLensDirection |
CameraLensDirection | 是 | 相机的方向。可能的值 (CameraLensDirection.back, CameraLensDirection.front, CameraLensDirection.external) |
设置闪光灯模式
将相机的闪光灯模式设置为指定的 flashMode
(关闭、开启、自动等)。
此函数在 BaseMixinFeatureCameraV2
中可用。
void screenFunction() {
setFlashMode(FlashMode.always);
}
参数名称 | 类型 | 必填 | 描述 |
---|---|---|---|
flashMode |
FlashMode | 是 | 可以为相机设置的可能闪光灯模式。可能的值 (FlashMode.off, FlashMode.auto, FlashMode.always, FlashMode.torch) |
拍摄照片
使用活动相机捕获照片并返回文件。
此函数在 BaseMixinFeatureCameraV2
中可用。
void screenFunction() {
takePicture(includeExif: true);
}
参数名称 | 类型 | 必填 | 描述 |
---|---|---|---|
includeExif |
bool | 否 | 如果为true,则返回exif数据。 |
流式相机
开始流式传输相机图像数据,并每两秒触发一次 onImageStream
。
此函数在 BaseMixinFeatureCameraV2
中可用。
void startStreamCamera() {
startImageStream(onImageStream: onImageStream);
}
Future<void> onImageStream(CameraImage cameraImage,
int sensorOrientation,
DeviceOrientation deviceOrientation,
CameraLensDirection cameraLensDirection,) async {
// 处理流式图像
}
使用示例
矩形覆盖层
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("相机ID卡页面", style: TextStyle(color: Colors.black)),
),
body: Stack(
children: [
// 相机预览区域
Container(
alignment: Alignment.center,
child: cameraController?.value.isInitialized == true
? CameraPreview(cameraController!)
: Container(),
),
// ID卡捕捉的覆盖矩形
IgnorePointer(
child: CustomPaint(
painter: RectanglePainterV2(),
child: Container(),
),
),
],
),
);
}
基础相机
class CustomCameraPage extends StatefulWidget {
const CustomCameraPage({super.key});
[@override](/user/override)
State<CustomCameraPage> createState() => _CustomCameraPageState();
}
class _CustomCameraPageState extends State<CustomCameraPage> with BaseMixinFeatureCameraV2 {
[@override](/user/override)
void initState() {
super.initState();
addListener(onFlashModeChanged: onFlashModeChanged);
initializeCamera(
cameraLensDirection: CameraLensDirection.back,
onCameraInitialized: onCameraInitialized,
onCameraInitializedFailure: (FeatureCameraException exception) {},
);
}
void onCameraInitialized(CameraController controller) {
setState(() {});
}
}
基础相机 - 流式相机
class CustomCameraPage extends StatefulWidget {
const CustomCameraPage({super.key});
[@override](/user/override)
State<CustomCameraPage> createState() => _CustomCameraPageState();
}
class _CustomCameraPageState extends State<CustomCameraPage> with BaseMixinFeatureCameraV2 {
[@override](/user/override)
void initState() {
super.initState();
addListener(onFlashModeChanged: onFlashModeChanged);
initializeStreamingCamera(
onCameraInitialized: onCameraInitialized,
onCameraInitializedFailure: (FeatureCameraException exception) {},
cameraLensDirection: CameraLensDirection.front,
);
}
void onCameraInitialized(CameraController controller) {
setState(() {});
}
}
特性相机
计算图像亮度
计算图像的亮度。
- 0.0 过暗
- 0.5 正常
- 1.0 过亮
final brightnessImage = FeatureCamera.calculateBrightness("imageBytes");
// 处理图像亮度
使用说明
更多详细示例请参见 示例。
示例代码
import 'package:example/data/dto/model/feature_model.dart';
import 'package:example/data/enum/preview_type.dart';
import 'package:example/presentation/preview_id_card_page_v2.dart';
import 'package:example/presentation/preview_image_page.dart';
import 'package:example/presentation/preview_selfie_page_v2.dart';
import 'package:example/presentation/widget/feature_widget.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter相机示例',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MainPage(),
);
}
}
class MainPage extends StatefulWidget {
const MainPage({super.key});
[@override](/user/override)
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
List<FeatureModel> features = [
FeatureModel(
title: '拍摄图像',
desc: '拍摄图像',
key: 'CAPTURE_IMAGE',
),
FeatureModel(
title: '流式图像',
desc: '流式图像',
key: 'STREAM_IMAGE',
),
FeatureModel(
title: '自拍相机V2',
desc: '自拍相机V2',
key: 'SELFIE_CAMERA_V2',
),
FeatureModel(
title: '身份证相机V2',
desc: '身份证相机V2',
key: 'ID_CARD_CAMERA_V2',
),
];
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('相机示例')),
body: ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
itemCount: features.length,
itemBuilder: (_, index) {
final feature = features[index];
return GestureDetector(
onTap: () async {
switch (feature.key) {
case "CAPTURE_IMAGE":
Navigator.of(context).push(MaterialPageRoute(builder: (_) => const PreviewImagePage(previewType: PreviewType.capture)));
break;
case "STREAM_IMAGE":
Navigator.of(context).push(MaterialPageRoute(builder: (_) => const PreviewImagePage(previewType: PreviewType.stream)));
break;
case "SELFIE_CAMERA_V2":
Navigator.of(context).push(MaterialPageRoute(builder: (_) => const PreviewSelfiePageV2()));
break;
case "ID_CARD_CAMERA_V2":
Navigator.of(context).push(MaterialPageRoute(builder: (_) => const PreviewIdCardPage2()));
break;
}
},
child: ItemFeatureWidget(feature: feature),
);
},
),
);
}
}
更多关于Flutter相机功能插件flutter_feature_camera的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter相机功能插件flutter_feature_camera的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter中使用flutter_feature_camera
(注意:这个包名可能是一个假设的,实际中常用的相机插件是camera
。但我会基于camera
插件给出示例,因为flutter_feature_camera
并非官方或广泛认知的插件)来实现相机功能的代码案例。如果你实际使用的确实是flutter_feature_camera
,请确保查阅其官方文档并进行相应调整。
首先,确保在你的pubspec.yaml
文件中添加了camera
插件依赖:
dependencies:
flutter:
sdk: flutter
camera: ^0.x.x # 请替换为最新版本号
然后运行flutter pub get
来安装依赖。
接下来,在你的Flutter项目中,你可以按照以下步骤使用相机功能:
- 请求相机权限(在Android和iOS上都需要):
在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/Runner/Info.plist
中添加:
<key>NSCameraUsageDescription</key>
<string>需要访问相机</string>
- 创建相机预览页面:
创建一个新的Dart文件(例如camera_page.dart
),并添加以下代码:
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
List<CameraDescription> cameras;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
cameras = await availableCameras();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '相机示例',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: CameraPage(cameraDescription: cameras.first),
);
}
}
class CameraPage extends StatefulWidget {
final CameraDescription cameraDescription;
CameraPage({Key? key, required this.cameraDescription}) : super(key: key);
@override
_CameraPageState createState() => _CameraPageState();
}
class _CameraPageState extends State<CameraPage> {
late CameraController _controller;
late Future<void> _initializeControllerFuture;
@override
void initState() {
super.initState();
_controller = CameraController(
widget.cameraDescription,
ResolutionPreset.high,
enableAudio: true,
);
_initializeControllerFuture = _controller.initialize();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('相机预览'),
),
body: FutureBuilder<void>(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// 如果相机已经初始化,显示预览
return CameraPreview(_controller);
} else {
// 否则,显示加载指示器
return Center(child: CircularProgressIndicator());
}
},
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
// 拍照逻辑
final image = await _controller.takePicture();
// 处理图片,例如保存到设备
final path = image.path;
print('图片路径: $path');
},
tooltip: '拍照',
child: Icon(Icons.camera_alt),
),
);
}
}
这个示例展示了如何初始化相机控制器,显示相机预览,并添加了一个浮动按钮来拍照。拍照后,图片的路径会被打印到控制台。
- 运行应用:
确保你的设备或模拟器已经连接,并运行flutter run
来启动应用。你应该能看到相机预览,并能够通过浮动按钮拍照。
请注意,这只是一个基础示例,实际应用中你可能需要处理更多的细节,比如处理图像数据、添加UI元素、处理错误等。此外,务必根据最新的camera
插件文档进行调整,因为API可能会随着版本的更新而发生变化。