Flutter图片选择插件hl_image_picker_android的使用

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

Flutter图片选择插件hl_image_picker_android的使用

简介

hl_image_picker_androidhl_image_picker 的 Android 实现,简化了在 Flutter 应用中选择、裁剪和拍摄媒体文件的过程。你可以从图库中选择图片或视频,裁剪图片,并通过相机拍摄新的照片或视频。

Picker Android

安装

在你的 pubspec.yaml 文件中添加以下依赖:

dependencies:
  hl_image_picker_android: ^latest_version

然后运行以下命令安装插件:

$ flutter pub add hl_image_picker_android

设置

1. 修改 build.gradle 文件

确保在 android/app/build.gradle 文件中设置 minSdkVersion 至少为 21:

android {
    ...
    defaultConfig {
        minSdkVersion 21
        ...
    }
}

2. 添加权限到 AndroidManifest.xml

<!-- Android 12及以下 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<!-- 针对 Android 13及以上 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />

<!-- 请求相机权限 -->
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />

<!-- 如果需要录制视频,请添加此权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />

使用

从图库中选择图片/视频

import 'package:hl_image_picker_android/hl_image_picker_android.dart';

final _picker = HLImagePickerAndroid();

List<HLPickerItem> _selectedImages = [];

_openPicker() async {
    final images = await _picker.openPicker(
        cropping: _isCroppingEnabled,
        selectedIds: _includePrevSelected
            ? _selectedImages.map((e) => e.id).toList()
            : null,
        pickerOptions: HLPickerOptions(
          mediaType: _type,
          enablePreview: _enablePreview,
          isExportThumbnail: _isExportThumbnail,
          thumbnailCompressFormat: CompressFormat.jpg,
          thumbnailCompressQuality: 0.9,
          maxSelectedAssets: _count,
          usedCameraButton: _usedCameraButton,
          numberOfColumn: _numberOfColumn,
          isGif: true,
        ),
        cropOptions: HLCropOptions(
          aspectRatio: _aspectRatio,
          aspectRatioPresets: _aspectRatioPresets,
          compressQuality: _compressQuality,
          compressFormat: CompressFormat.jpg,
        ),
    );
    setState(() {
        _selectedImages = images;
    });
}

拍摄照片或录制视频

_openCamera() async {
    try {
      final image = await _picker.openCamera(
        cropping: _isCroppingEnabled,
        cameraOptions: HLCameraOptions(
          cameraType:
              _type == MediaType.video ? CameraType.video : CameraType.image,
          recordVideoMaxSecond: 40,
          isExportThumbnail: _isExportThumbnail,
          thumbnailCompressFormat: CompressFormat.jpg,
          thumbnailCompressQuality: 0.9,
        ),
        cropOptions: HLCropOptions(
          aspectRatio: _aspectRatio,
          aspectRatioPresets: _aspectRatioPresets,
        ),
      );
      setState(() {
        _selectedImages = [image];
      });
    } catch (e) {
      debugPrint(e.toString());
    }
}

打开图片裁剪器

_openCropper() async {
    try {
      if (_selectedImages.isEmpty) {
        return;
      }
      final image = await _picker.openCropper(
        _selectedImages[0].path,
        cropOptions: HLCropOptions(
          aspectRatio: _aspectRatio,
          aspectRatioPresets: _aspectRatioPresets,
          compressQuality: _compressQuality,
          compressFormat: CompressFormat.jpg,
        ),
      );
      setState(() {
        _selectedImages = [image];
      });
    } catch (e) {
      debugPrint(e.toString());
    }
}

示例代码

以下是一个完整的示例代码,展示了如何使用 hl_image_picker_android 插件进行图片选择、拍照和裁剪。

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

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Image Picker Demo',
      home: MyHomePage(title: 'Image Picker Example'),
    );
  }
}

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

  final String? title;

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

class _MyHomePageState extends State<MyHomePage> {
  final _picker = HLImagePickerAndroid();

  List<HLPickerItem> _selectedImages = [];

  bool _isCroppingEnabled = false;
  int _count = 4;
  MediaType _type = MediaType.all;
  bool _isExportThumbnail = true;
  bool _enablePreview = false;
  bool _usedCameraButton = true;
  int _numberOfColumn = 3;
  bool _includePrevSelected = false;
  CropAspectRatio? _aspectRatio;
  List<CropAspectRatioPreset>? _aspectRatioPresets;
  double _compressQuality = 0.9;

  _openPicker() async {
    try {
      final images = await _picker.openPicker(
        cropping: _isCroppingEnabled,
        selectedIds: _includePrevSelected
            ? _selectedImages.map((e) => e.id).toList()
            : null,
        pickerOptions: HLPickerOptions(
          mediaType: _type,
          enablePreview: _enablePreview,
          isExportThumbnail: _isExportThumbnail,
          thumbnailCompressFormat: CompressFormat.jpg,
          thumbnailCompressQuality: 0.9,
          maxSelectedAssets: _count,
          usedCameraButton: _usedCameraButton,
          numberOfColumn: _numberOfColumn,
          isGif: true,
        ),
        cropOptions: HLCropOptions(
          aspectRatio: _aspectRatio,
          aspectRatioPresets: _aspectRatioPresets,
          compressQuality: _compressQuality,
          compressFormat: CompressFormat.jpg,
        ),
      );
      setState(() {
        _selectedImages = images;
      });
    } catch (e) {
      debugPrint(e.toString());
    }
  }

  _openCamera() async {
    try {
      final image = await _picker.openCamera(
        cropping: _isCroppingEnabled,
        cameraOptions: HLCameraOptions(
          cameraType:
              _type == MediaType.video ? CameraType.video : CameraType.image,
          recordVideoMaxSecond: 40,
          isExportThumbnail: _isExportThumbnail,
          thumbnailCompressFormat: CompressFormat.jpg,
          thumbnailCompressQuality: 0.9,
        ),
        cropOptions: HLCropOptions(
          aspectRatio: _aspectRatio,
          aspectRatioPresets: _aspectRatioPresets,
        ),
      );
      setState(() {
        _selectedImages = [image];
      });
    } catch (e) {
      debugPrint(e.toString());
    }
  }

  _openCropper() async {
    try {
      if (_selectedImages.isEmpty) {
        return;
      }
      final image = await _picker.openCropper(
        _selectedImages[0].path,
        cropOptions: HLCropOptions(
          aspectRatio: _aspectRatio,
          aspectRatioPresets: _aspectRatioPresets,
          compressQuality: _compressQuality,
          compressFormat: CompressFormat.jpg,
        ),
      );
      setState(() {
        _selectedImages = [image];
      });
    } catch (e) {
      debugPrint(e.toString());
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text(widget.title!),
        ),
        body: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // 媒体预览部分
              MediaPreview(items: _selectedImages),

              // 打开选择器按钮
              Align(
                child: ElevatedButton(
                  onPressed: _openPicker,
                  child: const Text('Open Picker'),
                ),
              ),

              // 打开相机按钮
              Align(
                child: ElevatedButton(
                  onPressed: _openCamera,
                  child: const Text('Open camera'),
                ),
              ),

              // 打开裁剪器按钮
              Align(
                child: ElevatedButton(
                  onPressed: _selectedImages.isNotEmpty ? _openCropper : null,
                  child: const Text('Open cropper'),
                ),
              ),

              // 配置部分
              Padding(
                padding: const EdgeInsets.all(16.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Padding(
                      padding: EdgeInsets.only(bottom: 16.0),
                      child: Text('Configuration',
                          style: TextStyle(
                              fontSize: 16, fontWeight: FontWeight.bold)),
                    ),
                    // 其他配置项...
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

更多关于Flutter图片选择插件hl_image_picker_android的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter图片选择插件hl_image_picker_android的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用hl_image_picker_android插件来选择图片的示例代码。

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

dependencies:
  flutter:
    sdk: flutter
  hl_image_picker_android: ^最新版本号  # 替换为最新版本号

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

接下来,在android/app/src/main/AndroidManifest.xml文件中添加必要的权限,因为选择图片需要访问设备的存储:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp">

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

    <!-- 其他配置 -->

</manifest>

注意:从Android 6.0(API 级别 23)开始,运行时权限是必需的。你可能需要在运行时请求这些权限。

接下来,在你的Dart代码中,你可以按照以下步骤使用hl_image_picker_android插件:

  1. 导入插件包。
  2. 使用插件的方法来选择图片。
  3. 处理选择的图片。

下面是一个完整的示例:

import 'package:flutter/material.dart';
import 'package:hl_image_picker_android/hl_image_picker_android.dart';
import 'dart:io';

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

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

class ImagePickerScreen extends StatefulWidget {
  @override
  _ImagePickerScreenState createState() => _ImagePickerScreenState();
}

class _ImagePickerScreenState extends State<ImagePickerScreen> {
  File? _selectedImage;

  void _pickImage() async {
    try {
      // 选择图片
      var result = await HlImagePickerAndroid.pickImage();
      
      // 检查结果是否成功
      if (result != null && result.code == 200) {
        // 获取图片路径
        var imagePath = result.data!;
        
        // 将图片路径转换为File对象
        setState(() {
          _selectedImage = File(imagePath);
        });
      } else {
        // 处理错误
        print("Failed to pick image: ${result?.msg}");
      }
    } catch (e) {
      // 处理异常
      print("Error picking image: $e");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Image Picker Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _selectedImage == null
                ? Text('No image selected.')
                : Image.file(_selectedImage!),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _pickImage,
              child: Text('Pick Image'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,其中包含一个按钮和一个显示所选图片的Image组件。当用户点击按钮时,会调用_pickImage方法来选择图片,并将选择的图片显示在屏幕上。

请确保你根据项目的实际需求调整代码,并处理运行时权限请求(如果需要的话)。

回到顶部