Flutter通用相机功能插件camera_universal的使用

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

Flutter通用相机功能插件camera_universal的使用

camera_universal 是一个用于在Flutter应用中实现相机功能的插件。本文将介绍如何安装和使用这个插件,并提供一个完整的示例demo。

安装

首先,你需要在你的Flutter项目中添加 camera_universal 依赖。打开终端并运行以下命令:

flutter pub add camera_universal

快速开始

下面是一个简单的示例代码,展示了如何使用 camera_universal 插件来初始化相机、激活相机以及处理相机相关的错误情况。

示例代码

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:camera_universal/camera_universal.dart';

void main(List<String> args) async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(
    const MaterialApp(
      home: MainApp(),
    ),
  );
}

class MainApp extends StatefulWidget {
  const MainApp({super.key});

  [@override](/user/override)
  State<MainApp> createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> {
  CameraController cameraController = CameraController();

  [@override](/user/override)
  void initState() {
    super.initState();
    task();
  }

  Future<void> task() async {
    try {
      await cameraController.initializeCameras();
      await cameraController.initializeCamera(setState: setState);
      await cameraController.activateCamera(
        setState: setState,
        mounted: () => mounted,
      );
    } catch (e, stack) {
      if (kDebugMode) {
        print(e);
        print(stack);
      }
    }
  }

  [@override](/user/override)
  void dispose() {
    cameraController.dispose();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: Camera(
        cameraController: cameraController,
        onCameraNotInit: (context) => const SizedBox.shrink(),
        onCameraNotSelect: (context) => const SizedBox.shrink(),
        onCameraNotActive: (context) => const SizedBox.shrink(),
        onPlatformNotSupported: (context) => const SizedBox.shrink(),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          if (kDebugMode) {
            print(await cameraController.action_change_camera(
              camera_id: 1,
              setState: setState,
              mounted: () => mounted,
              onCameraNotInit: () {},
              onCameraNotSelect: () {},
              onCameraNotActive: () {},
            ));
          }
        },
        child: const Icon(Icons.add_circle_outline_sharp),
      ),
    );
  }
}

完整示例Demo

以下是包含更多功能(如拍照和切换摄像头)的完整示例代码:

import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:camera_universal/camera_universal.dart';

void main(List<String> args) async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MaterialApp(home: MainApp()));
}

class MainApp extends StatefulWidget {
  const MainApp({super.key});

  [@override](/user/override)
  State<MainApp> createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> {
  CameraController cameraController = CameraController();
  String error_msg = "";

  [@override](/user/override)
  void initState() {
    super.initState();
    task();
  }

  Future<void> task() async {
    try {
      await cameraController.initializeCameras();
      await cameraController.initializeCamera(setState: setState);

      await cameraController.activateCamera(
        setState: setState,
        mounted: () => mounted,
      );
    } catch (e, stack) {
      if (kDebugMode) {
        print(e);
        print(stack);
      }
      setState(() {
        error_msg = "Error initializing camera";
      });
    }
  }

  [@override](/user/override)
  void dispose() {
    cameraController.dispose();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: ConstrainedBox(
        constraints: BoxConstraints(),
        child: Stack(
          children: [
            Visibility(
              visible: error_msg.isEmpty,
              replacement: Text(error_msg),
              child: Camera(
                cameraController: cameraController,
                onCameraNotInit: (context) => const Text("Camera not init"),
                onCameraNotSelect: (context) => const Text("Camera not select"),
                onCameraNotActive: (context) => const Text("Camera not active"),
                onPlatformNotSupported: (context) => const Text("Camera not supported"),
              ),
            ),
            Positioned(
              left: 0,
              right: 0,
              bottom: 0,
              child: Container(
                height: MediaQuery.of(context).size.height * 1 / 5,
                decoration: BoxDecoration(color: const Color.fromARGB(102, 0, 0, 0)),
                padding: const EdgeInsets.all(20),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    ElevatedButton(
                      onPressed: () async {},
                      style: ElevatedButton.styleFrom(shape: CircleBorder(), padding: const EdgeInsets.all(24)),
                      child: RotatedBox(
                        quarterTurns: 3,
                        child: Icon(Icons.more_horiz_rounded, size: 50, color: Colors.white),
                      ),
                    ),
                    ElevatedButton(
                      onPressed: () async {
                        final res = await cameraController.action_take_picture(
                          onCameraNotInit: () {},
                          onCameraNotSelect: () {},
                          onCameraNotActive: () {},
                        );

                        if (res != null) {
                          showDialog(
                            context: context,
                            builder: (context) {
                              return Dialog(
                                child: Column(
                                  mainAxisSize: MainAxisSize.min,
                                  crossAxisAlignment: CrossAxisAlignment.stretch,
                                  children: [
                                    Padding(
                                      padding: const EdgeInsets.only(left: 8.0),
                                      child: Row(
                                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                        children: [
                                          const Text('PICTURE', style: TextStyle(fontWeight: FontWeight.bold)),
                                          IconButton(
                                            onPressed: () => Navigator.of(context).pop(),
                                            icon: const Icon(Icons.close_rounded, color: Colors.redAccent),
                                          ),
                                        ],
                                      ),
                                    ),
                                    Image.file(File(res.path), fit: BoxFit.cover),
                                  ],
                                ),
                              );
                            },
                          );
                        }
                      },
                      style: ElevatedButton.styleFrom(shape: CircleBorder(), padding: const EdgeInsets.all(24)),
                      child: const Icon(Icons.camera_alt, size: 50, color: Colors.white),
                    ),
                    ElevatedButton(
                      onPressed: () async {
                        int cameraId = 1;
                        final res = cameraController.camera_mobile_datas;
                        if (cameraController.camera_id > 1) {
                          cameraId = 1;
                        } else {
                          cameraId = res.length;
                        }
                        await cameraController.action_change_camera(
                          cameraId: cameraId,
                          setState: setState,
                          mounted: () => mounted,
                          onCameraNotInit: () {},
                          onCameraNotSelect: () {},
                          onCameraNotActive: () {},
                        );
                      },
                      style: ElevatedButton.styleFrom(shape: CircleBorder(), padding: const EdgeInsets.all(24)),
                      child: const Icon(Icons.camera_alt, size: 50, color: Colors.white),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

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

1 回复

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


当然,以下是如何在Flutter项目中使用camera_universal插件来实现通用相机功能的代码示例。请注意,camera_universal插件的具体实现和API可能会随着版本的更新而变化,因此以下代码是基于插件的一般使用方式编写的,并假设你已经正确安装和配置了该插件。

首先,确保在你的pubspec.yaml文件中添加camera_universal依赖:

dependencies:
  flutter:
    sdk: flutter
  camera_universal: ^最新版本号  # 替换为实际的最新版本号

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

接下来,你需要配置你的AndroidManifest.xmlInfo.plist文件以请求相机权限。这通常在你安装相机插件时,插件的README文件中会有详细的说明。

以下是一个简单的Flutter应用示例,展示了如何使用camera_universal插件来访问相机并显示实时预览:

import 'package:flutter/material.dart';
import 'package:camera_universal/camera_universal.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Camera Universal Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: CameraScreen(),
    );
  }
}

class CameraScreen extends StatefulWidget {
  @override
  _CameraScreenState createState() => _CameraScreenState();
}

class _CameraScreenState extends State<CameraScreen> {
  CameraController? _controller;
  Future<void>? _initializeControllerFuture;

  @override
  void initState() {
    super.initState();
    _initializeControllerFuture = _initializeCameraController();
  }

  @override
  void dispose() {
    _controller?.dispose();
    super.dispose();
  }

  Future<void> _initializeCameraController() async {
    // 如果相机可用,则初始化相机控制器
    final cameras = await availableCameras();
    if (cameras.isNotEmpty) {
      _controller = CameraController(
        cameras.first,
        ResolutionPreset.medium,
      );

      // 监听相机图像流
      _controller!.initialize().then((_) {
        if (mounted) {
          setState(() {});
        }
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Camera Preview'),
      ),
      body: FutureBuilder<void>(
        future: _initializeControllerFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            // 如果相机已经初始化,则显示预览
            if (snapshot.hasError) {
              return Text('Error: ${snapshot.error!}');
            } else if (!_controller!.value.isInitialized) {
              return CircularProgressIndicator();
            } else {
              return CameraPreview(_controller!);
            }
          } else {
            // 否则显示加载指示器
            return CircularProgressIndicator();
          }
        },
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.camera),
        onPressed: () async {
          // 这里可以添加拍照或录像的功能,具体实现取决于camera_universal插件的API
          // 例如: await _controller!.takePicture();
          // 注意:这里的API调用是假设性的,请查阅camera_universal的文档以获取正确的API调用方式
        },
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,它使用camera_universal插件来初始化相机并显示实时预览。请注意,由于camera_universal插件的具体API可能与示例中的假设API不同,因此你需要查阅该插件的官方文档来获取正确的API调用方式。

此外,由于camera_universal可能不是Flutter社区广泛使用的标准相机插件(如camera插件),因此在实际项目中,请确保该插件满足你的需求,并关注其维护状态和社区支持情况。如果可能的话,考虑使用更广泛支持和维护的插件。

回到顶部