Flutter相机功能插件camerawesome的使用

发布于 1周前 作者 nodeper 来自 Flutter

Flutter相机功能插件camerawesome的使用

简介

CamerAwesome 是一个Flutter插件,旨在简化在应用程序中嵌入相机体验的过程。它提供了一个完全可定制的相机界面,您可以使用内置的优秀界面或根据需要进行自定义。

Apparence Preview Features

安装与使用

添加依赖

pubspec.yaml文件中添加以下内容:

dependencies:
  camerawesome: ^2.0.0-dev.1

平台特定设置

iOS

ios/Runner/Info.plist文件中添加以下权限:

<key>NSCameraUsageDescription</key>
<string>Your own description</string>

<key>NSMicrophoneUsageDescription</key>
<string>To enable microphone access when recording video</string>

<key>NSLocationWhenInUseUsageDescription</key>
<string>To enable GPS location access for Exif data</string>

Android

android/app/build.gradle文件中修改最小SDK版本为21(或更高):

minSdkVersion 21

如果您希望录制带有音频的视频,请在AndroidManifest.xml文件中添加以下权限:

<uses-permission android:name="android.permission.RECORD_AUDIO" />

如果您希望保存图片的位置信息,请添加以下权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

导入包

在您的Flutter应用中导入CamerAwesome包:

import 'package:camerawesome/camerawesome_plugin.dart';

使用内置界面

只需使用我们的构造器即可创建完整的相机体验:

CameraAwesomeBuilder.awesome(
  saveConfig: SaveConfig.photoAndVideo(),
  onMediaTap: (mediaCapture) {
    OpenFile.open(mediaCapture.filePath);
  },
),

创建自定义界面

如果内置界面不够用,可以使用custom()构造器来自定义界面:

CameraAwesomeBuilder.custom(
  saveConfig: SaveConfig.photo(),
  builder: (state, previewSize, previewRect) {
    // 在这里创建您的界面
  },
)

监听媒体捕获事件

使用onMediaCaptureEvent监听图片或视频捕获事件:

onMediaCaptureEvent: (event) {
  switch ((event.status, event.isPicture, event.isVideo)) {
    case (MediaCaptureStatus.capturing, true, false):
      debugPrint('Capturing picture...');
    case (MediaCaptureStatus.success, true, false):
      event.captureRequest.when(
        single: (single) {
          debugPrint('Picture saved: ${single.file?.path}');
        },
        multiple: (multiple) {
          multiple.fileBySensor.forEach((key, value) {
            debugPrint('multiple image taken: $key ${value?.path}');
          });
        },
      );
    case (MediaCaptureStatus.failure, true, false):
      debugPrint('Failed to capture picture: ${event.exception}');
    case (MediaCaptureStatus.capturing, false, true):
      debugPrint('Capturing video...');
    case (MediaCaptureStatus.success, false, true):
      event.captureRequest.when(
        single: (single) {
          debugPrint('Video saved: ${single.file?.path}');
        },
        multiple: (multiple) {
          multiple.fileBySensor.forEach((key, value) {
            debugPrint('multiple video taken: $key ${value?.path}');
          });
        },
      );
    case (MediaCaptureStatus.failure, false, true):
      debugPrint('Failed to capture video: ${event.exception}');
    default:
      debugPrint('Unknown event: $event');
  }
},

示例代码

以下是一个完整的示例代码,展示了如何在Flutter应用中使用CamerAwesome插件:

import 'dart:io';

import 'package:camerawesome/camerawesome_plugin.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';

void main() {
  runApp(const CameraAwesomeApp());
}

class CameraAwesomeApp extends StatelessWidget {
  const CameraAwesomeApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'camerAwesome',
      home: CameraPage(),
    );
  }
}

class CameraPage extends StatelessWidget {
  const CameraPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: Colors.white,
        child: CameraAwesomeBuilder.awesome(
          onMediaCaptureEvent: (event) {
            switch ((event.status, event.isPicture, event.isVideo)) {
              case (MediaCaptureStatus.capturing, true, false):
                debugPrint('Capturing picture...');
              case (MediaCaptureStatus.success, true, false):
                event.captureRequest.when(
                  single: (single) {
                    debugPrint('Picture saved: ${single.file?.path}');
                  },
                  multiple: (multiple) {
                    multiple.fileBySensor.forEach((key, value) {
                      debugPrint('multiple image taken: $key ${value?.path}');
                    });
                  },
                );
              case (MediaCaptureStatus.failure, true, false):
                debugPrint('Failed to capture picture: ${event.exception}');
              case (MediaCaptureStatus.capturing, false, true):
                debugPrint('Capturing video...');
              case (MediaCaptureStatus.success, false, true):
                event.captureRequest.when(
                  single: (single) {
                    debugPrint('Video saved: ${single.file?.path}');
                  },
                  multiple: (multiple) {
                    multiple.fileBySensor.forEach((key, value) {
                      debugPrint('multiple video taken: $key ${value?.path}');
                    });
                  },
                );
              case (MediaCaptureStatus.failure, false, true):
                debugPrint('Failed to capture video: ${event.exception}');
              default:
                debugPrint('Unknown event: $event');
            }
          },
          saveConfig: SaveConfig.photoAndVideo(
            initialCaptureMode: CaptureMode.photo,
            photoPathBuilder: (sensors) async {
              final Directory extDir = await getTemporaryDirectory();
              final testDir = await Directory(
                '${extDir.path}/camerawesome',
              ).create(recursive: true);
              if (sensors.length == 1) {
                final String filePath =
                    '${testDir.path}/${DateTime.now().millisecondsSinceEpoch}.jpg';
                return SingleCaptureRequest(filePath, sensors.first);
              }
              // Separate pictures taken with front and back camera
              return MultipleCaptureRequest(
                {
                  for (final sensor in sensors)
                    sensor:
                        '${testDir.path}/${sensor.position == SensorPosition.front ? 'front_' : "back_"}${DateTime.now().millisecondsSinceEpoch}.jpg',
                },
              );
            },
            videoOptions: VideoOptions(
              enableAudio: true,
              ios: CupertinoVideoOptions(
                fps: 10,
              ),
              android: AndroidVideoOptions(
                bitrate: 6000000,
                fallbackStrategy: QualityFallbackStrategy.lower,
              ),
            ),
            exifPreferences: ExifPreferences(saveGPSLocation: true),
          ),
          sensorConfig: SensorConfig.single(
            sensor: Sensor.position(SensorPosition.back),
            flashMode: FlashMode.auto,
            aspectRatio: CameraAspectRatios.ratio_4_3,
            zoom: 0.0,
          ),
          enablePhysicalButton: true,
          previewAlignment: Alignment.center,
          previewFit: CameraPreviewFit.contain,
          onMediaTap: (mediaCapture) {
            mediaCapture.captureRequest.when(
              single: (single) {
                debugPrint('single: ${single.file?.path}');
                single.file?.open();
              },
              multiple: (multiple) {
                multiple.fileBySensor.forEach((key, value) {
                  debugPrint('multiple file taken: $key ${value?.path}');
                  value?.open();
                });
              },
            );
          },
          availableFilters: awesomePresetFiltersList,
        ),
      ),
    );
  }
}

通过以上步骤,您可以在Flutter应用中轻松集成并使用CamerAwesome插件来实现强大的相机功能。更多详细信息请参考官方文档


更多关于Flutter相机功能插件camerawesome的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter相机功能插件camerawesome的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用camera_awesome插件来实现相机功能的示例代码。camera_awesome是一个功能强大的Flutter相机插件,提供了多种相机配置和控制选项。

首先,确保你已经在你的pubspec.yaml文件中添加了camera_awesome依赖:

dependencies:
  flutter:
    sdk: flutter
  camera_awesome: ^0.10.0  # 请检查最新版本号

然后,运行flutter pub get来安装依赖。

接下来,是一个完整的示例代码,展示如何使用camera_awesome插件来实现基本的相机功能:

主应用代码 (main.dart)

import 'package:flutter/material.dart';
import 'package:camera_awesome/camera_awesome.dart';
import 'package:camera_awesome/camera_awesome_flutter.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CameraAwesomePage(),
    );
  }
}

class CameraAwesomePage extends StatefulWidget {
  @override
  _CameraAwesomePageState createState() => _CameraAwesomePageState();
}

class _CameraAwesomePageState extends State<CameraAwesomePage> {
  late CameraController _cameraController;
  bool _isTakingPicture = false;

  @override
  void initState() {
    super.initState();
    _initCameraController().then((_) {
      if (mounted) {
        setState(() {});
      }
    });
  }

  Future<void> _initCameraController() async {
    try {
      _cameraController = await CameraController.init(
        CameraOptions(
          facing: CameraFacing.back,
          resolution: CameraResolution.high,
          enableAudio: false,
        ),
      );
      _cameraController.addListener(() {
        if (mounted) setState(() {});
      });
      await _cameraController.initialize();
    } catch (e) {
      print(e);
    }
  }

  @override
  void dispose() {
    _cameraController.dispose();
    super.dispose();
  }

  Future<void> _takePicture() async {
    if (!_isTakingPicture) {
      setState(() {
        _isTakingPicture = true;
      });
      try {
        final CameraImage? image = await _cameraController.captureImage();
        if (image != null) {
          // 在这里处理捕获的图片,比如保存到文件系统
          // 注意:image.planes和image.format包含了图片的原始数据
          print('Image captured successfully');
        }
      } catch (e) {
        print(e);
      } finally {
        if (mounted) {
          setState(() {
            _isTakingPicture = false;
          });
        }
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Camera Awesome Example'),
      ),
      body: _cameraController.value.isInitialized
          ? CameraPreview(_cameraController)
          : Center(child: CircularProgressIndicator()),
      floatingActionButton: FloatingActionButton(
        onPressed: _takePicture,
        tooltip: 'Take Picture',
        child: Icon(_isTakingPicture ? Icons.stop : Icons.camera_alt),
      ),
    );
  }
}

权限处理

由于访问相机需要权限,你还需要在AndroidManifest.xmlInfo.plist中添加相应的权限声明。

Android (AndroidManifest.xml)

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- 如果需要音频 -->
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

iOS (Info.plist)

<key>NSCameraUsageDescription</key>
<string>Need camera access to capture images</string>
<key>NSMicrophoneUsageDescription</key> <!-- 如果需要音频 -->
<string>Need microphone access to record audio</string>

注意事项

  1. 权限请求:在实际应用中,你需要处理权限请求和拒绝的情况。可以使用permission_handler插件来简化这个过程。
  2. 图片处理:上述示例中并未包含图片保存或显示的具体代码,你可以使用path_providerimage插件来处理这些功能。
  3. 错误处理:示例代码中的错误处理较为简单,在实际应用中应该更加完善。

通过这些步骤,你应该能够在Flutter应用中成功集成并使用camera_awesome插件来实现相机功能。

回到顶部