How to upload multiple images using Dio and multi_image_picker plugin in Flutter
Solution 1
Here's how to get a list of byte arrays from a list of Asset
s:
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);
}
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.
sreng bona
Updated on December 17, 2022Comments
-
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 fromList<Asset>
toList<File>
so if you have any solutions help me.try to use:
multi_image_picker: ^4.6.1
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,),), ), ), ), ), ], ), ); } }