Flutter人脸裁剪插件face_cropper的使用

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

Flutter人脸裁剪插件face_cropper的使用

face_cropper 是一个用于在图像中检测人脸并返回裁剪后的人脸图像的 Flutter 插件。

预览

face_cropper_2024-02-21

安装

首先,在 pubspec.yaml 文件中添加 face_cropper 作为依赖项:

dependencies:
  face_cropper: ^<latest-version>

然后运行 flutter pub get 命令以安装该库。

iOS

  • 最低 iOS 部署目标版本为 13.0。
  • ios/Runner/Info.plist 文件中添加以下内容:
<key>NSPhotoLibraryUsageDescription</key>
<string>your usage description here</string>

Android

  • android/app/build.gradle 文件中的最低 Android SDK 版本改为 21 或更高:
minSdkVersion 21

使用

  1. 导入依赖
import 'package:face_cropper/face_cropper.dart';
  1. 创建 FaceCropper 实例
FaceCropper faceCropper = FaceCropper();
  1. 使用 detectFacesAndCrop 方法获取裁剪后的图像路径
String imagePath = await faceCropper.detectFacesAndCrop('<path_to_image>');

该方法返回一个字符串,表示裁剪后的图像路径。

示例代码

以下是一个完整的示例代码,展示了如何使用 face_cropper 插件来选择图像并裁剪其中的人脸:

import 'dart:io';

import 'package:face_cropper/face_cropper.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

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

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

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

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> {
  String? _imagePath;
  String? _croppedImagePath;
  bool isLoading = false;
  FaceCropper faceCropper = FaceCropper();

  void _pickImage() async {
    try {
      final pickedImagePath = await ImagePicker().pickImage(source: ImageSource.gallery);

      if (pickedImagePath != null) {
        setState(() {
          _imagePath = pickedImagePath.path;
        });
      } else {
        ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
          content: Text("未选择图片"),
        ));
      }
    } catch (error, stackTrace) {
      print(error.toString());
      print(stackTrace.toString());
    }
  }

  void _clearAll() {
    setState(() {
      _imagePath = null;
      _croppedImagePath = null;
    });
  }

  void _cropFace() async {
    setState(() {
      isLoading = true;
    });

    if (_imagePath == null || _imagePath!.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
        backgroundColor: Colors.red,
        content: Text("检测人脸时出错"),
      ));
      setState(() {
        isLoading = false;
      });
      return;
    }

    final croppedImage = await faceCropper.detectFacesAndCrop(_imagePath!);
    if (croppedImage != null) {
      setState(() {
        _croppedImagePath = croppedImage;
      });
    }

    setState(() {
      isLoading = false;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: SizedBox(
        width: double.infinity,
        height: double.infinity,
        child: Padding(
          padding: const EdgeInsets.all(20.0),
          child: Column(
            children: [
              isLoading
                  ? const SizedBox(
                      height: 400,
                      width: 400,
                      child: Center(
                        child: SizedBox(
                          height: 50,
                          width: 50,
                          child: CircularProgressIndicator(),
                        ),
                      ),
                    )
                  : Row(
                      children: [
                        Expanded(
                          child: InkWell(
                            onTap: () {
                              if (_imagePath != null) {
                                return;
                              }
                              _pickImage();
                            },
                            borderRadius: BorderRadius.circular(10),
                            splashColor: Colors.blue,
                            child: Container(
                              height: 400,
                              width: 400,
                              decoration: BoxDecoration(
                                  color: _imagePath != null
                                      ? Colors.transparent
                                      : Colors.grey.shade300,
                                  borderRadius: BorderRadius.circular(10)),
                              child: _imagePath == null
                                  ? const Icon(Icons.upload)
                                  : Image.file(
                                      File.fromUri(
                                        Uri.parse(_imagePath!),
                                      ),
                                      fit: BoxFit.contain,
                                    ),
                            ),
                          ),
                        ),
                        if (_croppedImagePath != null)
                          const SizedBox(
                            width: 10,
                          ),
                        if (_croppedImagePath != null)
                          Expanded(
                            child: Container(
                              height: 400,
                              width: 400,
                              decoration: BoxDecoration(
                                  color: _imagePath != null
                                      ? Colors.transparent
                                      : Colors.grey.shade300,
                                  borderRadius: BorderRadius.circular(10)),
                              child: _imagePath == null
                                  ? const Icon(Icons.upload)
                                  : Image.file(
                                      File.fromUri(
                                        Uri.parse(_croppedImagePath!),
                                      ),
                                      fit: BoxFit.contain,
                                    ),
                            ),
                          ),
                      ],
                    ),
              const SizedBox(
                height: 30,
              ),
              if (_imagePath != null) ...[
                if (_croppedImagePath == null)
                  ElevatedButton(
                    onPressed: _cropFace,
                    child: const Text('人脸裁剪'),
                  ),
                ElevatedButton(
                  onPressed: _clearAll,
                  child: const Text('清除'),
                ),
              ],
              if (_imagePath == null)
                Text(
                  '选择图片',
                  style: Theme.of(context).textTheme.bodyLarge,
                )
            ],
          ),
        ),
      ),
    );
  }
}

更多关于Flutter人脸裁剪插件face_cropper的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter人脸裁剪插件face_cropper的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用face_cropper插件进行人脸裁剪的示例代码。这个插件允许用户从图像中选择并裁剪人脸区域。

首先,确保你的Flutter项目中已经添加了face_cropper插件。在你的pubspec.yaml文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  face_cropper: ^2.0.0  # 请确保版本号是最新的

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

接下来,在你的Flutter应用中,你可以按照以下步骤使用face_cropper插件:

  1. 导入必要的包
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:face_cropper/face_cropper.dart';

注意:face_cropper依赖于image_picker来选择图像,因此你还需要添加image_picker依赖。

  1. 定义状态和变量
class FaceCropperExample extends StatefulWidget {
  @override
  _FaceCropperExampleState createState() => _FaceCropperExampleState();
}

class _FaceCropperExampleState extends State<FaceCropperExample> {
  File? _imageFile;
  File? _croppedImageFile;

  final ImagePicker _picker = ImagePicker();
  late FaceCropper _cropper;

  @override
  void initState() {
    super.initState();
    _cropper = FaceCropper();
  }
  1. 实现图像选择和裁剪功能
  Future<void> _pickImage() async {
    final pickedFile = await _picker.pickImage(source: ImageSource.camera);

    if (pickedFile != null) {
      setState(() {
        _imageFile = File(pickedFile.path);
      });

      // 显示裁剪界面
      _cropImage();
    }
  }

  Future<void> _cropImage() async {
    if (_imageFile == null) return;

    final cropResult = await _cropper.cropImage(
      sourcePath: _imageFile!.path,
      aspectRatioPresets: [
        CropAspectRatioPreset.square,
        CropAspectRatioPreset.ratio3x2,
        CropAspectRatioPreset.original,
        CropAspectRatioPreset.ratio4x3,
        CropAspectRatioPreset.ratio16x9
      ],
      androidUiSettings: AndroidUiSettings(
        toolbarTitle: 'Cropper',
        toolbarColor: Colors.deepOrange,
        toolbarWidgetColor: Colors.white,
        initAspectRatio: CropAspectRatioPreset.original,
        lockAspectRatio: false,
      ),
      iosUiSettings: IOSUiSettings(
        minimumAspectRatio: 1.0,
      ),
    );

    if (cropResult == null) {
      return;
    }

    setState(() {
      _croppedImageFile = File(cropResult.path);
    });
  }
  1. 构建UI
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Face Cropper Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              _imageFile != null
                  ? Image.file(
                      _imageFile!,
                      width: 300,
                      height: 300,
                      fit: BoxFit.cover,
                    )
                  : Text('No image selected.'),

              SizedBox(height: 20),

              _croppedImageFile != null
                  ? Image.file(
                      _croppedImageFile!,
                      width: 150,
                      height: 150,
                      fit: BoxFit.cover,
                    )
                  : Text('No cropped image.'),

              SizedBox(height: 20),

              ElevatedButton(
                onPressed: _pickImage,
                child: Text('Pick and Crop Image'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
  1. 运行应用

确保你的设备或模拟器已连接,并运行flutter run来启动应用。现在你应该能够选择一张图片,并通过face_cropper插件进行裁剪。

这个示例展示了如何结合使用image_pickerface_cropper插件来实现基本的图像选择和裁剪功能。根据你的具体需求,你可以进一步定制这些功能。

回到顶部