Flutter相机检测插件inspection_camera的使用

Flutter相机检测插件inspection_camera的使用

安装

  1. 在你的 pubspec.yaml 文件中添加最新版本的插件,并运行 dart pub get
dependencies:
  inspection_camera: ^0.0.1+11
  1. 导入插件并将其用于你的 Flutter 应用程序:
import 'package:inspection_camera/inspection_camera.dart';

示例

以下是一个完整的示例代码,展示了如何在 Flutter 中使用 inspection_camera 插件来拍照和录制视频。

示例代码

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

void main() {
  try {
    runApp(const MyApp());
  } catch (e) {
    print(e);
  }
}

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Camera POC'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final List<InspectionMedia?> images = [];

  final TextEditingController textEditingController = TextEditingController(text: "3");
  bool loading = false;

  Future<T> loadingWrapper<T>(Future<T> Function() callback) async {
    setState(() {
      loading = true;
    });
    try {
      return await callback.call();
    } finally {
      setState(() {
        loading = false;
      });
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView(
        children: [
          if (!loading) ...[
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: ElevatedButton(
                child: const Text('拍摄单张照片'),
                onPressed: () async {
                  loadingWrapper(() async {
                    final image = await CameraModule(
                        navigationHandler: NavigationHandler.defaultNavigator(context),
                        defaultCaptureConfig: ImageCaptureConfig(
                          cameraModuleCallbacks: ImageCaptureCallbacks(
                              onCameraLoaded: () {},
                              onRotationPrompt: (a) {},
                              onFlashToggle: (a) {},
                              onCapture: () {},
                              onPreviewLoad: () {},
                              onPreviewAccepted: () {},
                              onPreviewRejected: () {},
                              onRetakeClick: () async {
                                bool valueToReturn = false;
                                await showDialog(
                                    context: context,
                                    builder: (context) {
                                      return AlertDialog(
                                        title: const Text(
                                          '当前图像将被丢弃。',
                                        ),
                                        actions: [
                                          InkWell(
                                              onTap: () {
                                                Navigator.pop(context);
                                                valueToReturn = true;
                                              },
                                              child: const Text('确定')),
                                          InkWell(
                                              onTap: () {
                                                Navigator.pop(context);
                                                valueToReturn = false;
                                              },
                                              child: const Text('取消')),
                                        ],
                                      );
                                    });
                                return valueToReturn;
                              }),
                        )).capture(
                      captureConfig: (defaultConfig) {
                        return defaultConfig;
                      },
                    );
                    if (image != null) {
                      setState(() {
                        images.insert(0, image);
                      });
                    }
                  });
                },
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: ElevatedButton(
                child: const Text('拍摄单个视频'),
                onPressed: () async {
                  loadingWrapper(() async {
                    final video = await CameraModule(
                      navigationHandler: NavigationHandler.defaultNavigator(context),
                    ).capture(
                      captureConfig: (defaultConfig) => VideoCaptureConfig(),
                    );
                    if (video != null) {
                      setState(() {
                        images.insert(0, video);
                      });
                    }
                  });
                },
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Row(
                children: [
                  Flexible(
                    child: TextFormField(
                      controller: textEditingController,
                      onChanged: (value) {
                        if (int.tryParse(value) == null && value.isNotEmpty) {
                          textEditingController.text = "1";
                        }
                        setState(() {});
                      },
                    ),
                  ),
                  Expanded(
                    child: ElevatedButton(
                      child: Text('拍摄 ${int.tryParse(textEditingController.text) ?? 1} 张照片'),
                      onPressed: () async {
                        loadingWrapper(() async {
                          await CameraModule(
                            navigationHandler: NavigationHandler.defaultNavigator(context),
                            defaultCaptureConfig: ImageCaptureConfig(
                                captureWidgetBuilders: CaptureWidgetBuilders(
                              shutterIconBuilder: (context) => const Placeholder(),
                            )),
                          ).captureMultiple(
                            captureConfigs: (defaultConfig) {
                              final List<MediaCaptureConfig> configs = [];
                              for (var i = 0; i < int.parse(textEditingController.text); i++) {
                                configs.add(defaultConfig);
                              }
                              return configs;
                            },
                            onPictureTaken: (index, captureConfig, data) {
                              images.insert(0, data);
                              setState(() {});
                            },
                          );
                        });
                      },
                    ),
                  ),
                ],
              ),
            ),
          ] else
            const Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Padding(
                  padding: EdgeInsets.all(8.0),
                  child: CircularProgressIndicator(),
                ),
              ],
            ),
          const Divider(),
          ...images.map(
            (e) => e == null
                ? Container()
                : switch (e) {
                    InspectionImage() => buildImage(context, e),
                    InspectionVideo() => Card(
                        child: Padding(
                          padding: const EdgeInsets.all(16.0),
                          child: buildStackVid(context, e.toWidget(), e.data),
                        ),
                      ),
                  },
          ),
        ],
      ),
    );
  }

  SizedBox buildImage(BuildContext context, InspectionImage e) {
    return SizedBox(
      width: MediaQuery.of(context).size.width,
      child: Card(
        child: Column(
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                FutureBuilder(
                  future: e.data.readAsBytes(),
                  builder: (context, snapshot) {
                    if (snapshot.hasData) {
                      return buildStack(
                        context,
                        e.toWidget(),
                        snapshot.data!,
                      );
                    } else {
                      return Container();
                    }
                  },
                ),
                FutureBuilder(
                  future: e.data.readAsBytes(),
                  builder: (context, snapshot) {
                    if (snapshot.hasData) {
                      return buildStack(
                        context,
                        e.toWidget(),
                        snapshot.data!,
                      );
                    } else {
                      return Container();
                    }
                  },
                ),
              ],
            ),
            ElevatedButton(
              onPressed: () async {
                if (kIsWeb) {
                  await FileSaver.instance.saveFile(
                    name: 'originalImage.png',
                    filePath: e.data.path,
                  );
                  await Future.delayed(
                    const Duration(seconds: 1),
                  );
                  await FileSaver.instance.saveFile(
                    name: 'editedImage.png',
                    bytes: await e.data.readAsBytes(),
                  );
                } else {
                  await ImageGallerySaver.saveFile(
                    e.data.path,
                  );
                  if (context.mounted) {
                    showDialog(
                      context: context,
                      builder: (context) {
                        return AlertDialog(
                          content: const Text('保存到相册!'),
                          actions: [
                            ElevatedButton(
                              onPressed: () => Navigator.pop(context),
                              child: const Text('关闭'),
                            ),
                          ],
                        );
                      },
                    );
                  }
                }
              },
              child: const Text(kIsWeb ? '下载' : '保存到相册'),
            )
          ],
        ),
      ),
    );
  }

  Stack buildStack(BuildContext context, Widget? e, Uint8List data) {
    return Stack(
      children: [
        SizedBox(
          width: MediaQuery.of(context).size.width * 0.45,
          child: e,
        ),
        Align(
          alignment: Alignment.topRight,
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: FloatingActionButton(
              child: const Icon(
                Icons.compress_rounded,
              ),
              onPressed: () {
                showDialog(
                  context: context,
                  builder: (context) => CompressionDialog(data: data),
                );
              },
            ),
          ),
        )
      ],
    );
  }

  Stack buildStackVid(BuildContext context, Widget? e, XFile data) {
    return Stack(
      children: [
        SizedBox(
          width: MediaQuery.of(context).size.width * 0.45,
          child: e,
        ),
        Align(
          alignment: Alignment.topRight,
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: FloatingActionButton(
              child: const Icon(
                Icons.compress_rounded,
              ),
              onPressed: () {
                showDialog(
                  context: context,
                  builder: (context) => CompressionDialogVideo(data: data),
                );
              },
            ),
          ),
        )
      ],
    );
  }
}

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

1 回复

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


inspection_camera 是一个 Flutter 插件,用于在 Flutter 应用中实现相机检测功能。它允许你访问设备的摄像头并进行实时检测,通常用于需要图像处理或计算机视觉的应用场景。

以下是如何在 Flutter 项目中使用 inspection_camera 插件的基本步骤:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 inspection_camera 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  inspection_camera: ^latest_version

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

2. 导入包

在你的 Dart 文件中导入 inspection_camera 包:

import 'package:inspection_camera/inspection_camera.dart';

3. 初始化相机

初始化相机并开始预览:

class CameraPage extends StatefulWidget {
  [@override](/user/override)
  _CameraPageState createState() => _CameraPageState();
}

class _CameraPageState extends State<CameraPage> {
  InspectionCameraController? _controller;

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

  Future<void> _initializeCamera() async {
    _controller = InspectionCameraController();
    await _controller?.initialize();
    if (!mounted) return;
    setState(() {});
  }

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    if (_controller == null || !_controller!.value.isInitialized) {
      return Center(child: CircularProgressIndicator());
    }
    return InspectionCameraPreview(_controller!);
  }
}

4. 相机预览

使用 InspectionCameraPreview 来显示相机的实时预览:

InspectionCameraPreview(_controller!);

5. 处理图像帧

如果你需要对相机捕获的图像帧进行处理,可以通过 InspectionCameraController 来获取帧数据:

_controller?.startImageStream((CameraImage image) {
  // 处理图像帧
});

6. 释放资源

在页面销毁时,确保释放相机资源:

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

7. 其他功能

inspection_camera 插件可能还提供了其他功能,如切换摄像头、调整分辨率、拍照等。你可以查阅插件的文档来了解更多详细信息。

示例代码

以下是一个完整的示例代码,展示了如何使用 inspection_camera 插件:

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

class CameraPage extends StatefulWidget {
  [@override](/user/override)
  _CameraPageState createState() => _CameraPageState();
}

class _CameraPageState extends State<CameraPage> {
  InspectionCameraController? _controller;

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

  Future<void> _initializeCamera() async {
    _controller = InspectionCameraController();
    await _controller?.initialize();
    if (!mounted) return;
    setState(() {});
  }

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    if (_controller == null || !_controller!.value.isInitialized) {
      return Center(child: CircularProgressIndicator());
    }
    return Scaffold(
      appBar: AppBar(
        title: Text('Inspection Camera'),
      ),
      body: Column(
        children: [
          Expanded(
            child: InspectionCameraPreview(_controller!),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              IconButton(
                icon: Icon(Icons.camera_alt),
                onPressed: () async {
                  final image = await _controller?.takePicture();
                  if (image != null) {
                    // 处理拍摄的照片
                  }
                },
              ),
              IconButton(
                icon: Icon(Icons.switch_camera),
                onPressed: () {
                  _controller?.switchCamera();
                },
              ),
            ],
          ),
        ],
      ),
    );
  }
}
回到顶部