How to upload multiple images using Dio and multi_image_picker plugin in Flutter

6,851

Solution 1

Here's how to get a list of byte arrays from a list of Assets:

List<Asset> images;
...

List<ByteData> byteDataList = await Future.wait(images.map((Asset image) => image.getByteData()));

List<Uint8List> byteArrayList = byteDataList.map((ByteData byteData) {
  ByteBuffer byteBuffer = byteData.buffer;
  return byteBuffer.asUint8List(byteData.offsetInBytes, byteBuffer.lengthInBytes);
}).toList();

Now you can use the list of byte arrays to build a payload using your network client of choice. For those not using 3rd party networking clients, that would be a MultipartRequest with multiple MultipartFile.fromBytes.

Solution 2

You don't need to convert Asset into File, You can send is as a byte array.

Only need to create the Multipart object of each image.

You can get the byte array from the Assets

 ByteData byteData = await asset.getByteData();
  List<int> imageData = byteData.buffer.asUint8List();

then it can pass through MultipartFile.fromBytes() method.

so it will look like,

  String url = "upload/url";

          List<Asset> images = List<Asset>();
          List<MultipartFile> multipartImageList = new List<MultipartFile>();
          if (null != images) {
            for (Asset asset in images) {
              ByteData byteData = await asset.getByteData();
              List<int> imageData = byteData.buffer.asUint8List();
              MultipartFile multipartFile = new MultipartFile.fromBytes(
                imageData,
                filename: 'load_image',
                contentType: MediaType("image", "jpg"),
              );
              multipartImageList.add(multipartFile);
            }

            FormData formData = FormData.fromMap({
              "multipartFiles": multipartImageList,
              "userId": '1'
            });

            Dio dio = new Dio();
            var response = await dio.post(url, data: formData);
          }

FYI

Solution 3

when you pick images from gallery, called getFileList() and then called set state,first use global variable of list of file and clear each time this list when you again pick images.

  List<File> listFile = List<File>();
  images = resultList;
  _error = error;
   getFileList();

 void getFileList() async{
  listFile.clear();
 for(int i=0; i<images.length; i++){
  var path= await images[i].filePath;
  print(path);
  var file=await getImageFileFromAssets(path);
  print(file);
  listFile.add(file);
}
 setState(() {

 });
}

getImageFileFromAsset is used for conver asset to file

Future<File> getImageFileFromAsset(String path) async {
final file = File(path);
return file;

}

and use listFile in formdata.

Share:
6,851
sreng bona
Author by

sreng bona

Updated on December 17, 2022

Comments

  • sreng bona
    sreng bona over 1 year

    I want to upload multiple-images using Dio and multi_image_picker plug-in in Flutter.

    List<Asset> this is the problem because I can't convert from List<Asset> to List<File> so if you have any solutions help me.

    try to use:

    1. multi_image_picker: ^4.6.1

    2. dio: ^3.0.4

    Thanks

    Bona SR.

    import 'dart:io';
    import 'package:dio/dio.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter_secure_storage/flutter_secure_storage.dart';
    import 'package:merchantside/helper/colorhelper.dart';
    import 'package:merchantside/merchantside/login.dart';
    import 'dart:async';
    import 'package:multi_image_picker/multi_image_picker.dart';
    
    class ListImages extends StatefulWidget {
      String errorMessage = "";
      @override
      _ListImagesState createState() => new _ListImagesState();
    }
    
    class _ListImagesState extends State<ListImages> {
      List<Asset> images = List<Asset>();
      List<File> listImages = [];
      @override
      void initState() {
        super.initState();
      }
    
      Widget buildGridView() {
        return GridView.count(
          crossAxisCount: 3,
          children: List.generate(images.length, (index) {
            Asset asset = images[index];
            return AssetThumb(
              asset: asset,
              width: 300,
              height: 300,
            );
          }),
        );
      }
    
    
      void _uploadFiles() async {
        String uid = await FlutterSecureStorage().read(key: "getTocken");
        try {
          var dio = Dio();
          FormData formData = new FormData.fromMap({
            "pictures[]": images, 
          });
          Response resp = await dio.post(
            mainUrl + 'merchant/upload-galleries',
            data: formData,
            onSendProgress: (int sent, int total) {
              //
            }, 
            options: Options(
              headers: {
                HttpHeaders.authorizationHeader: uid,
              },
            )
          );
          if(resp.statusCode == 200) {
            print("============= Print Resp data: ");
            print(resp.data);
          }
    
        } catch (e) {
          print(e);
        }
      }
    
      Future<void> loadAssets() async {
        List<Asset> resultList = List<Asset>();
        try {
          resultList = await MultiImagePicker.pickImages(
            maxImages: 6,
            enableCamera: true,
            selectedAssets: images,
            cupertinoOptions: CupertinoOptions(takePhotoIcon: "chat"),
            materialOptions: MaterialOptions(
              actionBarColor: "#abcdef",
              actionBarTitle: "Example App",
              allViewTitle: "All Photos",
              useDetailsView: false,
              selectCircleStrokeColor: "#000000",
            ),
          );
        } on Exception catch (e) {
          print(e);
        }
    
        // If the widget was removed from the tree while the asynchronous platform
        // message was in flight, we want to discard the reply rather than calling
        // setState to update our non-existent appearance.
        if (!mounted) return;
        setState(() {
          images = resultList;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          floatingActionButton: FloatingActionButton(
            heroTag: "btn1",
            backgroundColor: ColorHelper.orange,
            child: Icon(Icons.add_photo_alternate),
            onPressed: loadAssets,
          ),
          appBar: new AppBar(
            title: Text('បញ្ជីរូបភាព'),
            backgroundColor: ColorHelper.orange,
          ),
          body: Column(
            children: <Widget>[
              //Error message
              errorMessage != "" ? 
              Container(
                margin: EdgeInsets.only(left: 10, right: 10, top: 10),
                height: 50,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.all(Radius.circular(4)),
                  color: ColorHelper.red.withOpacity(0.5),
                ),
                child: Center(
                  child: Text("$errorMessage", style: TextStyle(color: ColorHelper.swhite, fontSize: 15),),
                ),
              ):
              Container(),
    
              Expanded(
                child: Container(
                  margin: EdgeInsets.only(left: 10, right: 10, top: 10),
                  child: buildGridView(),
                ),
              ),
              SafeArea(
                child: Container(
                  margin: EdgeInsets.all(10),
                  decoration: BoxDecoration(
                    color: ColorHelper.green,
                    borderRadius: BorderRadius.all(Radius.circular(4))
                  ),
                  height: 50,
                  child: InkWell(
                    onTap: () {
                      if(images.length > 0) {
                        setState(() {
                          errorMessage = "";
                        });
                        // Call function upload multiple files
                        _uploadFiles();
                      } else {
                        setState(() {
                          errorMessage = "សូមបញ្ជូលរូបភាព";
                        });
                      } 
                    },
                    child: Center(
                      child: Text("រួចរាល់", style: TextStyle(color: ColorHelper.swhite, fontSize: 15, fontWeight: FontWeight.w500,),),
                    ),
                  ),
                ),
              ),
            ],
          ),
        );
      }
    }