Flutter原生拍照功能插件take_picture_native的使用

Flutter原生拍照功能插件take_picture_native的使用

take_picture_native 插件允许你从原生相机获取照片。以下是如何使用此插件的详细步骤。

获取开始

本项目是一个用于 Flutter 的插件包,它包括了针对 Android 和/或 iOS 的平台特定实现代码。

对于 Flutter 开发的入门帮助,你可以查看官方文档,其中包括教程、示例、移动开发指南以及完整的 API 参考。

使用示例

下面是一个完整的示例代码,展示了如何在 Flutter 应用中使用 take_picture_native 插件来实现拍照功能。

import 'dart:io';

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

import 'package:take_picture_native/take_picture_native.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  PictureDataModel? _pictureDataModel;

  @override
  void initState() {
    _pictureDataModel = PictureDataModel();
    _pictureDataModel!.inputClickState.add([]);

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text("TAKE PICTURE NATIVE"),
        ),
        body: Container(
          padding: const EdgeInsets.all(10.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Expanded(
                child: StreamBuilder<List<String>>(
                  stream: _pictureDataModel!.outputResult,
                  builder: (BuildContext context, AsyncSnapshot<List<String>> snapshot) {
                    return Container(
                      width: MediaQuery.of(context).size.width,
                      padding: const EdgeInsets.all(20.0),
                      child: snapshot.hasData
                          ? snapshot.data!.isNotEmpty
                              ? ClipRRect(
                                  borderRadius: BorderRadius.circular(20.0),
                                  child: Image.file(
                                    File(snapshot.data![0]),
                                    fit: BoxFit.contain,
                                  ),
                                )
                              : const SizedBox.shrink()
                          : const Center(
                              child: CircularProgressIndicator(),
                            ),
                    );
                  },
                ),
              ),
              const SizedBox(height: 20.0),
              ElevatedButton(
                style: ButtonStyle(
                  backgroundColor: MaterialStateProperty.all<Color>(Colors.blue),
                  shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                    RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(40.0),
                    ),
                  ),
                ),
                child: const Padding(
                  padding: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 20.0),
                  child: Text(
                    "CLICK",
                    style: TextStyle(
                      color: Colors.white,
                    ),
                  ),
                ),
                onPressed: () {
                  TakePictureNative.openCamera.then(
                    (List<String> data) {
                      _pictureDataModel!.inputClickState.add(data);
                    },
                    onError: (e) {
                      _pictureDataModel!.inputClickState.add([]);
                    },
                  );
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class PictureDataModel {
  final StreamController<List<String>> _streamController = StreamController<List<String>>.broadcast();

  Sink<List<String>> get inputClickState => _streamController;

  Stream<List<String>> get outputResult => _streamController.stream.map((data) => data);

  dispose() => _streamController.close();
}

代码解释

  • 导入必要的库

    import 'dart:io';
    import 'package:flutter/material.dart';
    import 'dart:async';
    import 'package:take_picture_native/take_picture_native.dart';
    
  • 定义主应用类

    void main() {
      runApp(const MyApp());
    }
    
  • 定义应用状态类

    class MyApp extends StatefulWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      PictureDataModel? _pictureDataModel;
    
      @override
      void initState() {
        _pictureDataModel = PictureDataModel();
        _pictureDataModel!.inputClickState.add([]);
    
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: const Text("TAKE PICTURE NATIVE"),
            ),
            body: Container(
              padding: const EdgeInsets.all(10.0),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  // 显示拍摄的照片
                  Expanded(
                    child: StreamBuilder<List<String>>(
                      stream: _pictureDataModel!.outputResult,
                      builder: (BuildContext context, AsyncSnapshot<List<String>> snapshot) {
                        return Container(
                          width: MediaQuery.of(context).size.width,
                          padding: const EdgeInsets.all(20.0),
                          child: snapshot.hasData
                              ? snapshot.data!.isNotEmpty
                                  ? ClipRRect(
                                      borderRadius: BorderRadius.circular(20.0),
                                      child: Image.file(
                                        File(snapshot.data![0]),
                                        fit: BoxFit.contain,
                                      ),
                                    )
                                  : const SizedBox.shrink()
                              : const Center(
                                  child: CircularProgressIndicator(),
                                ),
                        );
                      },
                    ),
                  ),
                  const SizedBox(height: 20.0),
                  // 拍照按钮
                  ElevatedButton(
                    style: ButtonStyle(
                      backgroundColor: MaterialStateProperty.all<Color>(Colors.blue),
                      shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                        RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(40.0),
                        ),
                      ),
                    ),
                    child: const Padding(
                      padding: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 20.0),
                      child: Text(
                        "CLICK",
                        style: TextStyle(
                          color: Colors.white,
                        ),
                      ),
                    ),
                    onPressed: () {
                      TakePictureNative.openCamera.then(
                        (List<String> data) {
                          _pictureDataModel!.inputClickState.add(data);
                        },
                        onError: (e) {
                          _pictureDataModel!.inputClickState.add([]);
                        },
                      );
                    },
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }
    
  • 定义数据模型类

    class PictureDataModel {
      final StreamController<List<String>> _streamController = StreamController<List<String>>.broadcast();
    
      Sink<List<String>> get inputClickState => _streamController;
    
      Stream<List<String>> get outputResult => _streamController.stream.map((data) => data);
    
      dispose() => _streamController.close();
    }
    

更多关于Flutter原生拍照功能插件take_picture_native的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

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


take_picture_native 是一个用于Flutter的原生拍照插件,它允许你在Flutter应用中直接调用设备的原生相机功能。以下是如何使用 take_picture_native 插件的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 take_picture_native 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  take_picture_native: ^1.0.0 # 使用最新版本

然后运行 flutter pub get 来获取依赖。

2. 导入插件

在你的Dart文件中导入 take_picture_native 插件:

import 'package:take_picture_native/take_picture_native.dart';

3. 调用拍照功能

使用 TakePictureNative 类来调用拍照功能。你可以通过 takePicture 方法来启动相机并获取拍摄的照片。

class CameraExample extends StatefulWidget {
  @override
  _CameraExampleState createState() => _CameraExampleState();
}

class _CameraExampleState extends State<CameraExample> {
  String? _imagePath;

  Future<void> _takePicture() async {
    try {
      final String? imagePath = await TakePictureNative.takePicture();
      if (imagePath != null) {
        setState(() {
          _imagePath = imagePath;
        });
      }
    } catch (e) {
      print("Error taking picture: $e");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Take Picture Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            if (_imagePath != null)
              Image.file(
                File(_imagePath!),
                width: 200,
                height: 200,
              )
            else
              Text('No image taken yet.'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _takePicture,
              child: Text('Take Picture'),
            ),
          ],
        ),
      ),
    );
  }
}

4. 处理权限

在Android和iOS上,使用相机功能需要相应的权限。确保你在 AndroidManifest.xmlInfo.plist 中配置了相机权限。

Android (android/app/src/main/AndroidManifest.xml):

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

iOS (ios/Runner/Info.plist):

<key>NSCameraUsageDescription</key>
<string>We need access to your camera to take pictures.</string>
回到顶部