Flutter选择多张图片上传

25 篇文章 0 订阅
8 篇文章 0 订阅

之前发过一篇上传多张图片的博客,那个是自己实现的,但是是一张一张上传最后页面上显示出来所有上传的图片,这篇文章介绍一下一次性选择多张图片并上传

首先引入依赖:multi_image_picker,这个插件可以选择多张图片,插件地址https://pub.flutter-io.cn/packages/multi_image_picker

然后画个小页面

import 'package:flutter/material.dart';
import 'dart:io';
//ByteData这里需要引入dart:typed_data文件,引入service.dart的话app里可以检索到文件个数,但是传递到后台一直是null,时间紧迫我也没抓包看是咋回事儿先这么用吧
import 'dart:typed_data';
import 'package:dio/dio.dart';
//MediaType用
import 'package:http_parser/http_parser.dart';
import 'package:multi_image_picker/multi_image_picker.dart';

class TestPage extends StatefulWidget {
  final arguments;
  TestPage({Key key, this.arguments}) : super(key : key);
  _TestPageState createState() => _TestPageState(this.arguments);
}

class _TestPageState extends State<TestPage> {
  final arguments;
  _TestPageState(this.arguments);
  //上传图片用
  ScrollController _imgController = new ScrollController();
  List<Asset> _img = new List<Asset>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: InkWell(
          child: Icon(Icons.keyboard_return),
          onTap: (){
            Navigator.pop(context);
          },
        ),
        title: Text("上传照片"),
      ),
      body: Padding(
        padding: EdgeInsets.all(10),
        child: Column(
          children: [
            Row(
              children: <Widget>[
                this._img == null ? Expanded(
                  flex: 1,
                  child: Text(""),
                ) : Expanded(
                  flex: 1,
                  child: Container(
                    width: double.infinity,
                    height: 50,
                    child: ListView.builder(
                      controller: _imgController,
                      shrinkWrap: true,
                      scrollDirection: Axis.horizontal,
                      itemCount: this._img.length,
                      itemBuilder: (context, index){
                        return Container(
                          width: 50,
                          height: 50,
                          margin: EdgeInsets.only(right: 10),
                          decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(4.0),
                              border: Border.all(
                                style: BorderStyle.solid,
                                color: Colors.black26,
                              )
                          ),
                          child: AssetThumb(
                            asset: this._img[index],
                            width: 50,
                            height: 50,
                          ),
                        );
                      },
                    ),
                  ),
                ),
                InkWell(
                  child: Container(
                    width: 50,
                    height: 50,
                    margin: EdgeInsets.only(right: 10),
                    decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(4.0),
                        border: Border.all(
                          style: BorderStyle.solid,
                          color: Colors.black26,
                        )
                    ),
                    child: Center(
                      child: Icon(Icons.camera_alt),
                    ),
                  ),
                  onTap: _openGallerySystem ,
                )
              ],
            ),
            Container(
              width: double.infinity,
              height: 80,
              child: RaisedButton(
                color: Colors.blue,
                child: Text(
                  "提交",
                  style: TextStyle(color: Colors.white),
                ),
                onPressed: () {
                  _submitData();
                },
              ),
            ),
          ],
        )
      ),
    );
  }

  //选择文件上传
  void _openGallerySystem () async {
    List<Asset> resultList = List<Asset>();
    resultList = await MultiImagePicker.pickImages(
      //最多选择几张照片
      maxImages: 9,
      //是否可以拍照
      enableCamera: true,
      selectedAssets: _img,
      materialOptions:MaterialOptions(
          startInAllView:true,
          allViewTitle:'所有照片',
          actionBarColor:'#2196F3',
          //未选择图片时提示
          textOnNothingSelected:'没有选择照片',
          //选择图片超过限制弹出提示
          selectionLimitReachedText: "最多选择9张照片"
      ),
    );
    if (!mounted) return;
    setState(() {
      _img = resultList;
    });
  }

  //提交数据
  void _submitData () async {
    //处理图片
    List<MultipartFile> imageList = new List<MultipartFile>();
    for (Asset asset in _img) {
      //将图片转为二进制数据
      ByteData byteData = await asset.getByteData();
      List<int> imageData = byteData.buffer.asUint8List();
      MultipartFile multipartFile = new MultipartFile.fromBytes(
        imageData,
        //这个字段要有,否则后端接收为null
        filename: 'load_image',
        //请求contentType,设置一下,不设置的话默认的是application/octet/stream,后台可以接收到数据,但上传后是.octet-stream文件
        contentType: MediaType("image", "jpg"),
      );
      imageList.add(multipartFile);
    }

    FormData formData = new FormData.fromMap({
      //后端要用multipartFiles接收参数,否则为null
      "multipartFiles" : imageList
    });
    var res = await Dio().post("你的URL", data: formData);
    //后面随意发挥
  }
}

选择图片截图:这个插件选择图片后还有个加载过程,挺好的(按钮有点丑,凑合看吧,哈哈哈)

后端方法:SpringBoot

@RequestMapping(value = "xxx", method = RequestMethod.POST)
    //一定要有这个注解@RequestParam("multipartFiles[]"),否则接收不到参数
    public String testupload (@RequestParam("multipartFiles[]") List<MultipartFile> multipartFiles) throws IOException {
        if (multipartFiles.size() > 0) {
            for (MultipartFile multipartFile : multipartFiles) {
                //上传图片
                BufferedImage image = ImageIO.read(multipartFile.getInputStream());
                System.out.println(image);
                String extention ="."+ multipartFile.getContentType().split("/")[1];
                UUID uuid = UUID.randomUUID();
                String path = "D:/haha/" + uuid+ extention;
                File outputFile = new File(path);
                ImageIO.write(image, "jpg", outputFile);
            }
        }
        return "ok";
    }

上传后截图:

中间还有个小波折,第一次测试程序的时候程序报了个错:The multi-part request contained parameter data (excluding uploaded files) that exceeded the limit for maxPostSize set on the associated connector

开始以为是图片的过大,但是我已经在项目中设置了

spring.servlet.multipart.max-file-size = 100MB

spring.servlet.multipart.max-request-size=100MB

感觉不应该是图片尺寸的问题,

后来网上找了办法说是springboot中的内置tomcat服务器限定了Httppost的最大size

解决办法:在properties中添加如下配置,修改该内置服务器的对HttpPost数据的大小

server.max-http-header-size=102400000

server.tomcat.max-http-post-size=102400000

参考链接:https://blog.csdn.net/Draught_Bear/article/details/105601473

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
为了在Flutter中实现图片上传,你可以使用`image_picker`和`dio`插件来调用系统相册和相机,并将选中的图片上传到服务器。 首先,你需要在Flutter项目的`pubspec.yaml`文件中添加`image_picker`和`dio`插件的依赖。 接下来,你可以使用`image_picker`插件的`getImage`方法来调用系统相册或相机,例如: ``` import 'package:image_picker/image_picker.dart'; final picker = ImagePicker(); // 调用相册 final pickedFile = await picker.getImage(source: ImageSource.gallery); // 调用相机 final pickedFile = await picker.getImage(source: ImageSource.camera); ``` 请注意,如果你需要支持多选图片,你需要在`pub.dev`上查找其他插件。 一旦你选择了图片,你可以使用`dio`插件将图片上传到服务器,例如: ``` import 'package:dio/dio.dart'; final dio = Dio(); FormData formData = FormData.fromMap({ 'file': await MultipartFile.fromFile(pickedFile.path), }); Response response = await dio.post('YOUR_UPLOAD_URL', data: formData); ``` 这里的`YOUR_UPLOAD_URL`是你的图片上传接口的URL,你需要根据实际情况进行替换。 以上是在Flutter中上传图片的基本方法,你可以根据实际需求进行更多的定制和处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [flutter基础:调用图库及图片上传](https://blog.csdn.net/weixin_40652755/article/details/109724270)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值