给image_picker添加自定义UI拍摄页面

  • 情形

插件常见使用:

dependencies:
 image_picker: ^0.8.4+11

但是在特殊情况下,比如拍摄身份证,我们需要自定义拍摄的UI页面以满足需求,但它本身是没有这个功能的。

这种情况下就需要我们去修改插件添加我们所需要的功能。

  • 分析(以iOS为例)

在"FLTImagePickerPlugin.m"文件中,关于"pickImage"方法的"imageSource"只有"SOURCE_GALLERY"和"SOURCE_CAMERA"两种:

if ([@"pickImage" isEqualToString:call.method]) {
   int imageSource = [call.arguments[@"source"] intValue];

   if (imageSource == SOURCE_GALLERY) {  // Capture is not possible with PHPicker
     if (@available(iOS 14, *)) {
       // PHPicker is used
       [self pickImageWithPHPicker:1];
     } else {
       // UIImagePicker is used
       [self launchUIImagePickerWithSource:imageSource];
     }
   } else {
     [self launchUIImagePickerWithSource:imageSource];
   }
 } 

查看代码发现,image_picker插件中引入的另一个插件"image_picker_platform_interface"。如下所示:

dependencies:
 flutter:
   sdk: flutter
 flutter_plugin_android_lifecycle: ^2.0.1
 image_picker_for_web: ^2.1.0
 image_picker_platform_interface: ^2.3.0  //image_picker插件的通用平台界面

而上面两种类型对应的"image_picker_platform_interface"中的"image_source.dart"文件中的ImageSource类型,如下所示:

enum ImageSource {
 /// Opens up the device camera, letting the user to take a new picture.
 camera,

 /// Opens the user's photo gallery.
 gallery,
}

所以,想在"FLTImagePickerPlugin.m"文件中给"pickImage"方法的imageSource增加类型,就需要在插件"image_picker_platform_interface"中的imageSource添加类型。由于插件"image_picker_platform_interface"是自动引入到插件"image_picker"中的,所以,要将修改后的插件"image_picker_platform_interface"以本地引入的形式引入,然后在"FLTImagePickerPlugin.m"文件中根据需要做逻辑处理。

  • 修改(以iOS为例)

1、把插件 "image_picker_platform_interface"改为本地引入

在插件"image_picker"中创建文件夹"plugins",下载插件"image_picker_platform_interface-2.4.4",然后放入plugins中,最后本地引入。

dependencies:
 flutter:
   sdk: flutter
 flutter_plugin_android_lifecycle: ^2.0.1
 image_picker_for_web: ^2.1.0
#  image_picker_platform_interface: ^2.3.0
 image_picker_platform_interface:
   path: ./plugins/image_picker_platform_interface-2.4.4
image.png

2、将"image_picker_for_web"注释掉

Pub get报如下错误:

Running "flutter pub get" in image_picker-0.8.4+11...           
Because image_picker depends on image_picker_for_web ^2.1.0 which depends on image_picker_platform_interface ^2.2.0, image_picker_platform_interface from hosted is required.
So, because image_picker depends on image_picker_platform_interface from path, version solving failed.
pub get failed (1; So, because image_picker depends on image_picker_platform_interface from path, version solving failed.)
Process finished with exit code 1

是指"image_picker_for_web"和"image_picker_platform_interface"版本不兼容,这里方便起见,将其注释掉,如果需要其功能的话,可将image_picker_platform_interface改成与image_picker_for_web不冲突的版本,其他步骤不变。

dependencies:
 flutter:
   sdk: flutter
 flutter_plugin_android_lifecycle: ^2.0.1
#  image_picker_for_web: ^2.1.0
#  image_picker_platform_interface: ^2.3.0
 image_picker_platform_interface:
   path: ./plugins/image_picker_platform_interface-2.4.4

3、给ImageSource添加类型

以添加自定义拍摄身份证正反面UI为例,添加SOURCE_FRONT_IDImage和SOURCE_BACK_IDImage两种类型。根据需要添加,名字自己定义。

enum ImageSource {
 /// Opens up the device camera, letting the user to take a new picture.
 camera,

 /// Opens the user's photo gallery.
 gallery,

 //自己需要增加的
 SOURCE_FRONT_IDImage,
 SOURCE_BACK_IDImage
}
image.png

4、将自定义文件放入插件对应的位置

添加自定义类.png

添加完成后,在example的iOS下执行"pod install",使修改的"image_picker.podspec"生效。

5、在"FLTImagePickerPlugin.m"添加逻辑处理

导入自定义类头文件

#import "CameraVC.h"
#import "FileManager.h"

添加Type类型:

static const int SOURCE_CAMERA = 0;
static const int SOURCE_GALLERY = 1;
static const int SOURCE_FRONT_IDImage = 2;//添加的
static const int SOURCE_BACK_IDImage = 3;//添加的

然后添加逻辑处理:

  if ([@"pickImage" isEqualToString:call.method]) {
    int imageSource = [call.arguments[@"source"] intValue];

    if (imageSource == SOURCE_GALLERY) {  // Capture is not possible with PHPicker
      if (@available(iOS 14, *)) {
        // PHPicker is used
        [self pickImageWithPHPicker:1];
      } else {
        // UIImagePicker is used
        [self launchUIImagePickerWithSource:imageSource];
      }
    } else  if (imageSource == SOURCE_CAMERA){
      [self launchUIImagePickerWithSource:imageSource];
    }
    //自己定义的,再此做逻辑处理  跳到自定义UI页面
     else  if (imageSource == SOURCE_FRONT_IDImage){
                       //身份证正面
                         CameraVC *vc = [[CameraVC alloc] init];
                         vc.isBack = false;
                         vc.imageblock = ^(UIImage * _Nonnull image) {
                             //返回图片路径
                             NSString *fileName = [NSString stringWithFormat:@"idCardFront-%d",arc4random()];
                             result([FileManager storeImage:UIImageJPEGRepresentation(image, 0.4f) withImageName:fileName]);

                         };
                         [[UIApplication sharedApplication].keyWindow.rootViewController addChildViewController:vc];
                         [[UIApplication sharedApplication].keyWindow.rootViewController.view addSubview:vc.view];

     } else if (imageSource == SOURCE_BACK_IDImage){
                      //身份证反面
                      CameraVC *vc = [[CameraVC alloc] init];
                       vc.isBack = YES;
                       vc.imageblock = ^(UIImage * _Nonnull image) {
                           //返回图片路径
                           NSString *fileName = [NSString stringWithFormat:@"idCardBack-%d",arc4random()];
                           result([FileManager storeImage:UIImageJPEGRepresentation(image, 0.4f) withImageName:fileName]);
                       };
                       [[UIApplication sharedApplication].keyWindow.rootViewController addChildViewController:vc];
                       [[UIApplication sharedApplication].keyWindow.rootViewController.view addSubview:vc.view];
       }


  } else if ([@"pickMultiImage" isEqualToString:call.method]) {}

同样,android部分按照iOS的逻辑类似处理,具体可看文章尾部的demo。

整体目录如下图所示:


image.png
  • 使用

在需要使用自定义拍摄UI的时候,source选用自己添加定义的ImageSource.SOURCE_FRONT_IDImage 或 ImageSource.SOURCE_BACK_IDImage:

 final ImagePicker _picker = ImagePicker();
    // Pick an image
    final XFile? image2 = await _picker.pickImage(source: ImageSource.SOURCE_FRONT_IDImage);
  • 效果

人像面:

1.jpg
2.jpg
3.jpg

国徽面:

1.jpg
2.jpg
3.jpg

Github的Demo地址:flutter_image_picker_custom_demo

你可能感兴趣的:(给image_picker添加自定义UI拍摄页面)