图片和文件的获取、上传

图片和文件选取

依赖库

主要用到两个依赖库,一个是image_picker,一个是file_picker
file_picker负责文件的选取,image_picker负责图片的选取

方法封装

file_picker支持多种方法,可获取单个、多个文件的目录和文件名。

从源码中一层层往上找到获取文件的主要方法,这里看获取多文件路径的方法getMultiFilePath,从一下的源码中可看出该方法调用了flutter自带的平台通道,从宿主机中获取指定扩展名的文件,再将文件路径通过/分开,并存入映射中,key为文件名,value为文件路径。单个文件类似。

Future<dynamic> _getPath(
    FileType fileType,
    bool allowMultipleSelection,
    bool allowCompression,
    List<String> allowedExtensions,
    Function(FilePickerStatus) onFileLoading,
) async {
    final String type = describeEnum(fileType);
    if (type != 'custom' && (allowedExtensions?.isNotEmpty ?? false)) {
    throw Exception(
        'If you are using a custom extension filter, please use the FileType.custom instead.');
    }
    try {
    _eventSubscription?.cancel();
    if (onFileLoading != null) {
        _eventSubscription = _eventChannel.receiveBroadcastStream().listen(
            (data) => onFileLoading((data as bool)
                ? FilePickerStatus.picking
                : FilePickerStatus.done),
            onError: (error) => throw Exception(error),
            );
    }

    dynamic result = await _channel.invokeMethod(type, {
        'allowMultipleSelection': allowMultipleSelection,
        'allowedExtensions': allowedExtensions,
        'allowCompression': allowCompression,
    });
    if (result != null && allowMultipleSelection) {
        if (result is String) {
        result = [result];
        }
        return Map<String, String>.fromIterable(result,
            key: (path) => path.split('/').last, value: (path) => path);
    }
    return result;
    } on PlatformException catch (e) {
    print('[$_tag] Platform exception: $e');
    rethrow;
    } catch (e) {
    print(
        '[$_tag] Unsupported operation. Method not found. The exception thrown was: $e');
    rethrow;
    }
}

因此对该方法进行封装如下,获取图片文件名以做后续处理:

Future getSingleImagePath() async{
    String SingleFilePath;
    SingleFilePath = await FilePicker.getFilePath(type: FileType.image);
    return SingleFilePath;
}

Future getMultiImagesPath() async{
    Map<String,String> imagesPaths;
    imagesPaths = await FilePicker.getMultiFilePath(type: FileType.image);

    //  Options
    //  List<String> allNames = filePaths.keys; // List of all file names
    //  List<String> allPaths = filePaths.values; // List of all paths
    //  String someFilePath = filePaths['fileName']; // Access a file path directly by its name (matching a key)

    return imagesPaths;
}
Future getMultiFilesPath() async{
    Map<String,String> filesPaths;
    filesPaths = await FilePicker.getMultiFilePath(type: FileType.image);

    //  Options
    //  List<String> allNames = filesPaths.keys; // List of all file names
    //  List<String> allPaths = filesPaths.values; // List of all paths
    //  String someFilePath = filesPaths['fileName']; // Access a file path directly by its name (matching a key)
    return filesPaths;
}

同时APP还要求有拍照的功能,使用另一个依赖库image_picker,源码与file_picker类似,不再贴出,主要使用该库的拍照功能,同样返回文件名,注意该依赖库的图片是暂存在临时目录中的:

Future getImageFileFromCamera() async{
    var picker = ImagePicker();
    PickedFile imageFile = await picker.getImage(source: ImageSource.camera,imageQuality: 50); //图片来源和压缩质量
    if(imageFile!=null){
        return File(imageFile.path).path;
    }
}

使用

在项目中的调用例子:

单文件

MultipartFile photo; //将文件转换为MulitipartFile类以供使用
String displayPath; //需要在页面上显示

void _selectFile() async {
    getSingleImagePath().then((path) {
    MultipartFile.fromFile(path).then((value) {
        photo = value;
    });

    setState(() {
        displayPath = path.toString();
    });
    });
}

void _selectFilefromCamera() async {
    getImageFileFromCamera().then((path) {
    MultipartFile.fromFile(path).then((value) {
        photo = value;
    });
    setState(() {
        displayPath = path.toString();
    });
    });
}

多文件

String filesname;
String filespath;
var flag2 = 0;
List displayPath = [];
List<MultipartFile> selectedFiles = new List<MultipartFile>();
Future<void> _selectFile() async {
    Map filesPaths;
    getMultiFilesPath().then((value) {
    filesPaths = value;
    var selectedFilePaths = filesPaths.values;
    MultipartFile tempfile;
    for (String path in selectedFilePaths) {
        displayPath.add(path);
        MultipartFile.fromFile(path).then((value) {
        if(value!=Null){
            flag2=1;
        }
        tempfile = value;
        selectedFiles.add(tempfile);
        print(selectedFiles.length);
        });
    }
    setState(() {
        filesname = displayPath.toString();
    });
    });
}

Future<void> _selectFilefromCamera() async {
    getImageFileFromCamera().then((value) {
    displayPath.add(value);
    var selectedFilePaths = value;
    MultipartFile tempfile;

    MultipartFile.fromFile(selectedFilePaths).then((value) {
        if(value!=Null){
            flag2=1;
        }
        tempfile = value;
        selectedFiles.add(tempfile);
        print(selectedFiles.length);
    });

    setState(() {
        filesname = displayPath.toString();
    });
    });
}

上传

利用之前写的网络模块

var register = Map();
GlobalKey<FormState> textFromKey = new GlobalKey<FormState>();
String phoneNumber;
String password;
String password2;
String verificationCode;
MultipartFile file;
bool isShowPassWord = false;
//读取当前的Form状态
var loginForm = textFromKey.currentState;
//验证Form表单
if (loginForm.validate()) {
  var register = Map();
  var map = Map();
  register['phoneNum'] = phoneNumber;
  register['passWord'] = password;
  register['verCode'] = verificationCode;
  register['file'] = file;
  map['register'] = register;
  FormData formData = FormData.fromMap(map);
  //网络部分
  DioManager.getInstance().post('PatientRegister', formData,
      (data){
    print(data);
      },
      (error){
    print(error);
      });

}else{
  ShowToast.getShowToast().showToast('请正确填写信息');
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值