2

我想将多张图片上传到 Rest API。我尝试使用以下代码将单个图像上传到其余 API。这很好,对于我使用multi_image_picker 链接的多张图片选择,我如何修改下面的代码来上传多张图片?谢谢

Future<String> uploadSingleImage(File file,String userid) async
  {

    final prefs = await SharedPreferences.getInstance();
    final key = 'token';
    final value = prefs.get(key ) ?? 0;

    String fileName = file.path.split("/").last;
    var stream =
    new http.ByteStream(DelegatingStream.typed(file.openRead()));

    // get file length

    var length = await file.length(); //imageFile is your image file
    Map<String, String> headers = {
      "Accept": "application/json",
      "Authorization": "Bearer $value"
    }; // ignore this headers if there is no authentication

    // string to uri
    var uri = Uri.parse(serverUrl + "/api/v1/upload_parent_image");

    // create multipart request
    var request = new http.MultipartRequest("POST", uri);

    // multipart that takes file
    var multipartFileSign = new http.MultipartFile('photo',
        stream,
        length,
        filename: fileName
    );

    // add file to multipart
    request.files.add(multipartFileSign);

    //add headers
    request.headers.addAll(headers);

    //adding params
    request.fields['id'] = userid;
   // request.fields['firstName'] = 'abc';
    // request.fields['lastName'] = 'efg';

    // send
    var response = await request.send();

    print(response.statusCode);

    // listen for response
    response.stream.transform(utf8.decoder).listen((value) {
      print(value);
    });
  }
4

5 回答 5

3

您可以将文件列表传递给您的方法,循环构建每个 MultipartFile 对象并将它们添加到您的 MultipartRequest

Future<String> uploadMultipleImage(List<File> files, String userid) async {
final prefs = await SharedPreferences.getInstance();
final key = 'token';
final value = prefs.get(key) ?? 0;

// string to uri
var uri = Uri.parse(serverUrl + "/api/v1/upload_parent_image");

// create multipart request
var request = new http.MultipartRequest("POST", uri);

for (var file in files) {
    String fileName = file.path.split("/").last;
    var stream = new http.ByteStream(DelegatingStream.typed(file.openRead()));

    // get file length

    var length = await file.length(); //imageFile is your image file

    // multipart that takes file
    var multipartFileSign = new http.MultipartFile('photo', stream, length, filename: fileName);

    request.files.add(multipartFileSign);
}

Map<String, String> headers = {
    "Accept": "application/json",
    "Authorization": "Bearer $value"
}; // ignore this headers if there is no authentication

//add headers
request.headers.addAll(headers);

//adding params
request.fields['id'] = userid;
// request.fields['firstName'] = 'abc';
// request.fields['lastName'] = 'efg';

// send
var response = await request.send();

print(response.statusCode);

// listen for response
response.stream.transform(utf8.decoder).listen((value) {
    print(value);
});
}
于 2020-03-27T23:45:34.447 回答
3

你的图片列表

List<String> photos = ["path of image1","path of image2", "path of image3",];



 List<http.MultipartFile> newList = [];

      for (var img in photos!) {
        if (img != "") {
          var multipartFile = await http.MultipartFile.fromPath(
            'Photos',
            File(img).path,
            filename: img.split('/').last,
          );
          newList.add(multipartFile);
        }
      }
request.files.addAll(newList);
于 2021-10-06T09:04:56.143 回答
0

我使用 dio 和 image_picker 依赖项发布此解决方案。它肯定会奏效。我花了 2 天时间来解决这个问题。

FormData formData = new FormData.fromMap({
  "name": "Max",
  "location": "Paris",
  "age": 21,
  "image[]": [
    await MultipartFile.fromFile(
      _imageFile.path,
    ),
    await MultipartFile.fromFile(
      _imageFile.path,
    ),
  ],
});

print(FormData1().then((value) {
  print(value);
}));
response = await dio.post(
 
  "http://143.110.244.110/radius/frontuser/eventsubmitbutton",
  data: formData,
  onSendProgress: (received, total) {
    if (total != -1) {
      print((received / total * 100).toStringAsFixed(0) + '%');
    }
  },
);
print(response);
于 2021-07-22T07:34:58.130 回答
0

我已经分享了我用来用这个包上传多个图像的代码

  multi_image_picker: ^4.8.0 
  flutter_absolute_path: ^1.0.6 
  flutter_image_compress:
  path_provider
http

使用flutter compress和path provider来压缩大小

Http请求代码

static Future<String> uploadMultipleImage({List<File> files}) async {
// string to uri
    var uri = Uri.parse("your api url");
    print("image upload URL - $uri");
// create multipart request
    var request = new http.MultipartRequest("POST", uri);

    for (var file in files) {
      String fileName = file.path.split("/").last;
      var stream = new http.ByteStream(DelegatingStream.typed(file.openRead()));

      // get file length

      var length = await file.length(); //imageFile is your image file
      print("File lenght - $length");
      print("fileName - $fileName");
      // multipart that takes file
      var multipartFileSign = new http.MultipartFile('images[]', stream, length,
          filename: fileName);

      request.files.add(multipartFileSign);
    }

    Map<String, String> headers = {
      "Accept": "application/json",
      "Authorization":
          "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxMiwiZXhwIjoxNjE3NTQyNDE0LCJpc3MiOiJsb2NhbGhvc3QiLCJpYXQiOjE2MTcxODI0MTR9.dGRbINOdx_tf417fpsjdQ5CR7uGULs98FjLGm2w4kRY"
    }; // ignore this headers if there is no authentication
    print("headers - $headers}");
//add headers
    request.headers.addAll(headers);

//adding params
    request.fields['heading'] = "heading";
    request.fields['description'] = "description";
    request.fields['mobile'] = "mobile";
    request.fields['email'] = "email";
    request.fields['category'] = "1";
    request.fields['location_type'] = "1";
    request.fields['location'] = "location";
    request.fields['lat'] = "12";
    request.fields['lng'] = "123";
    request.fields['price'] = "1231";
    request.fields['sub_category'] = "3";

// send
    var response = await request.send();

    print(response.statusCode);

    var res = await http.Response.fromStream(response);
    if (response.statusCode == 200 || response.statusCode == 201) {
      print("Item form is statuscode 200");
      print(res.body);
      var responseDecode = json.decode(res.body);

      if (responseDecode['status'] == true) {
        return res.body;
      } else {
        return res.body;
      }
    }

  }

我调用该方法的 UI 屏幕

    import 'dart:convert';
    import 'dart:io';
    
    import 'package:flutter/material.dart';
    import 'package:flutter_absolute_path/flutter_absolute_path.dart';
    import 'package:flutter_image_compress/flutter_image_compress.dart';
    import 'package:lookapt_olx_app/service/ApiService.dart';
    import 'package:lookapt_olx_app/utils/Utils.dart';
    import 'package:lookapt_olx_app/utils/colorUtils.dart';
    import 'package:lookapt_olx_app/utils/fontUtils.dart';
    import 'package:lookapt_olx_app/widgets/appbar_widget.dart';
    import 'package:lookapt_olx_app/widgets/commonWidget.dart';
    import 'package:lookapt_olx_app/widgets/textFieldWidget.dart';
    import 'package:lookapt_olx_app/widgets/textWidgets.dart';
    import 'package:multi_image_picker/multi_image_picker.dart';
    import 'package:rounded_loading_button/rounded_loading_button.dart';
    
    import 'addNewPostController.dart';
    import 'multiImagePicker.dart';
    import 'package:path_provider/path_provider.dart' as path_provider;
    
    class AddNewPostScreen extends StatefulWidget {
      Map<String, dynamic> parameters;
      String categoryId;
    
      AddNewPostScreen({this.parameters, this.categoryId = ""});
    
      @override
      _AddNewPostScreenState createState() => _AddNewPostScreenState();
    }
    
    class _AddNewPostScreenState extends State<AddNewPostScreen> {
      @override
      void initState() {
        super.initState();
        print("add new post");
        print(widget.parameters['name']);
        print(widget.categoryId.toString());
      }
    
      List<Asset> images = [];
      String _error = "";
    
      Widget buildGridView() {
        if (images != null)
          return GridView.count(
            crossAxisCount: 3,
            crossAxisSpacing: 10,
            children: List.generate(images.length, (index) {
              Asset asset = images[index];
              return AssetThumb(
                asset: asset,
                width: 300,
                height: 300,
              );
            }),
          );
        else
          return Container(color: Colors.white);
      }
    
      Future<void> loadAssets() async {
        setState(() {
          images = List<Asset>();
        });
    
        List<Asset> resultList;
        String error;
    
        try {
          resultList = await MultiImagePicker.pickImages(
            maxImages: 3,
          );
        } on Exception catch (e) {
          error = e.toString();
        }
    
        // 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;
    
          if (error == null) _error = 'Selected images';
        });
      }
    
      /*
      Usage
    
       final dir = await path_provider.getTemporaryDirectory();
    
                    final targetPath = dir.absolute.path + "/temp.jpg";
                    File imgFile = await testCompressAndGetFile(
                        File(_capturedImage.path), targetPath);
    
      * */
    
      Future<File> testCompressAndGetFile(File file, String targetPath) async {
        print("testCompressAndGetFile");
        final result = await FlutterImageCompress.compressAndGetFile(
          file.absolute.path,
          targetPath,
          quality: 30,
          minWidth: 1024,
          minHeight: 1024,
          // rotate: 90,
        );
        print(file.lengthSync());
        print(result.lengthSync());
    
        return result;
      }
    
      _uploadImageFun() async {
        print("Note - _getImagePaths called");
        List<File> fileImageArray = [];
        images.forEach((imageAsset) async {
          final filePath =
              await FlutterAbsolutePath.getAbsolutePath(imageAsset.identifier);
    
          File tempFile = File(filePath);
          print(filePath);
          print("filePath.length  - ${filePath.length}");
          print(tempFile);
          print("tempFile.length() - ${tempFile.lengthSync()}");
    
          if (tempFile.existsSync()) {

          DateTime now = DateTime.now();

            final dir = await path_provider.getTemporaryDirectory();
            final targetPath =
          dir.absolute.path + "/lookaptPostImage${now.microsecond}.jpg";

            File imgFile =
                await testCompressAndGetFile(File(tempFile.path), targetPath); 

            print("Compressed image");
            print(imgFile.lengthSync());
            fileImageArray.add(imgFile); //with image compress
          }
          if (fileImageArray.length == images.length) {
            var res = await ApiService.uploadMultipleImage(files: fileImageArray);
            print("image upload response");
            print(res);
            var resp = json.decode(res);
            if (resp['status'] == true) {
              SuccessToastWidget(context, message: resp['message']);
            } else {
              FailedToastWidget(context, message: resp['message']);
            }
          }
        });
        print("Test Prints");
        print(fileImageArray.length);
    
        return fileImageArray;
      }
    
      final RoundedLoadingButtonController _loginBtnController =
          new RoundedLoadingButtonController();
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: CommonAppBarWidget(title: widget.parameters['name'] ?? ""),
          body: _body(),
        );
      }
    
      AddNEwPostController _addNEwPostController = new AddNEwPostController();
    
      Widget _body() {
        return Padding(
          padding: const EdgeInsets.only(left: 20, right: 20, top: 10),
          child: ListView(
            children: [
            
              InkWell(
                onTap: loadAssets,
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(10),
                  child: Container(
                    color: Colors.grey.shade400,
                    child: ListTile(
                      leading: Icon(
                        Icons.add_box_outlined,
                        size: 30,
                        color: Colors.black,
                      ),
                      trailing: MyTextWidgets.textWidgetSemiBold(
                          str: "Pick Images", fontSize: 20),
                    ),
                  ),
                ),
              ),
              RoundedLoadingButton(
                child: MyTextWidgets.textWidgetBold(
                    fontSize: 16, str: "Next", color: MyColors.white.redC),
                controller: _loginBtnController,
                onPressed: () {
                  _getImagePaths();                 
                },
                width: MediaQuery.of(context).size.width,
                borderRadius: 10,
                color: MyColors.appGreenColor.redC,
                height: 44,
              ),
              Center(
                  child: _error == ""
                      ? Container()`enter code here`
                      : MyTextWidgets.textWidgetLight(str: _error)),
   
              Container(
                child: buildGridView(),
                height: 100,
                width: MediaQuery.of(context).size.width - 100,
              ),
             
            ],
          ),
        );
      }


}

笔记:

我的 ui 代码可能无法在您的代码中运行,因此只需从屏幕代码中复制所需的代码。

Http请求代码可以正常工作,只需复制并过去即可

感谢您的支持!

于 2021-03-31T11:41:33.187 回答
0

好吧,您几乎可以一次发送多个文件让我发布一些代码

Future<String> uploadSingleImage(File file,File file2,String userid) async
  {

    final prefs = await SharedPreferences.getInstance();
    final key = 'token';
    final value = prefs.get(key ) ?? 0;

    String fileName = file.path.split("/").last;
    var stream =
    new http.ByteStream(DelegatingStream.typed(file.openRead()));

    // get file length    
    var length = await file.length(); //imageFile is your image file
    Map<String, String> headers = {
      "Accept": "application/json",
      "Authorization": "Bearer $value"
    }; // ignore this headers if there is no authentication

    // string to uri
    var uri = Uri.parse(serverUrl + "/api/v1/upload_parent_image");

    // create multipart request
    var request = new http.MultipartRequest("POST", uri);

    // multipart that takes file
    var multipartFileSign = new http.MultipartFile('photo',
        stream,
        length,
        filename: fileName
    );

    // add file to multipart
    request.files.add(multipartFileSign);


   // Now Adding file 2 in request
   String fileName2 = file2.path.split("/").last;
    var stream2 =
    new http.ByteStream(DelegatingStream.typed(file2.openRead()));
    var lengthOfFile2 = await file2.length(); 

   // multipart that takes file
    var multipartFile2 = new http.MultipartFile('file2_key_here',
        stream2,
        lengthOfFile2,
        filename: fileName2
    );

   // add file2 to multipart
    request.files.add(multipartFile2);

    //add headers
    request.headers.addAll(headers);

    //adding params
    request.fields['id'] = userid;
   // request.fields['firstName'] = 'abc';
    // request.fields['lastName'] = 'efg';

    // send
    var response = await request.send();

    print(response.statusCode);

    // listen for response
    response.stream.transform(utf8.decoder).listen((value) {
      print(value);
    });
  }
于 2020-03-28T05:32:44.777 回答