使用 Flutter (iOS/Android) 将图像上传到 Azure blob

Posted

技术标签:

【中文标题】使用 Flutter (iOS/Android) 将图像上传到 Azure blob【英文标题】:Upload image to Azure blob using Flutter (iOS/Android) 【发布时间】:2021-03-15 21:17:45 【问题描述】:

我们如何将图像(.jpg、.png)上传到 Azure blob 存储。一开始没有任何见解。

如果您使用过示例,希望看到并尝试这样做,任何有效的示例/网址都将有助于开始使用

这是我正在尝试上传 .jpg 文件并收到 400 错误,

image.forEach((element) async 
    ImageDetailsUpload result = ImageDetailsUpload.fromJson(element);
    var postUri = Uri.parse('$url/$result.fileName?$code'); //Azure blob url
    var request = new http.MultipartRequest("PUT", postUri); //Put method
    request.files.add(
      new http.MultipartFile.fromBytes(
        'file',
        await File.fromUri(Uri.parse(result.path)).readAsBytes(),
      ),
    );
    request.send().then((response) 
      print(response.statusCode);
    , onError: (err) 
      print(err);
    );
  );

图像是一个列表并保存文件名和文件路径,这是我得到的字节(见下图)

解决了上传但图片在服务器上损坏的问题 -

image.forEach((element) async 
    ImageDetailsUpload result = ImageDetailsUpload.fromJson(element);
    var postUri = Uri.parse('$url/$result.fileName?$code');
    var request = new http.MultipartRequest("PUT", postUri);
    request.headers['X-MS-BLOB-TYPE'] = 'BlockBlob';

    request.files.add(
      new http.MultipartFile.fromBytes(
        'file',
        await File.fromUri(Uri.parse(result.path)).readAsBytes(),
      ),
    );
    request.send().then((response) 
      print(response.statusCode);
    , onError: (err) 
      print(err);
    );
  );

这似乎困扰着我。

还有更多问题,我注意到使用邮递员上传到 blob 存储的文件存储为image/jpeg 类型的实际图像,具体取决于我上传的图像类型。但是当使用应用程序上传时,我使用的是多部分,它使存储的文件成为multipart/form-data 类型。上传两种类型的图像 jpg/png 都给出了上面提到的类型。

[![在此处输入图片描述][3]][3]

【问题讨论】:

【参考方案1】:

如果您使用的是 HTTP,请在此处查看

How to upload images and file to a server in Flutter?

如果您使用的是 Dio,请检查此代码

FormData formData = FormData.from(
"name": "wendux",
"age": 25,
"file": await MultipartFile.fromFile("./text.txt",filename: "upload.txt")
);
response = await dio.post("/info", data: formData);

并查看 Dio 的文档 https://pub.dev/packages/dio

这是我的一个代码中的一个工作示例

Future<UploadImageResultModel> uploadImage(File image, String memberToken,
  String type = "IMAGE") async 
var uri = Uri.parse('$Constants.baseUrlmember/UploadImage/$type');
var request = new http.MultipartRequest("POST", uri);

request.headers.addAll(
  "Authentication": memberToken,
);

var stream = new http.ByteStream(DelegatingStream.typed(image.openRead()));
var length = await image.length();
var multipartFile = new http.MultipartFile('file', stream, length,
    filename: image.path.split("/").last);

request.files.add(multipartFile);

var streamedResponse = await request.send();

var response = await http.Response.fromStream(streamedResponse);

if (response.statusCode != 200)
  return UploadImageResultModel.fromJson(json.decode(""));

return UploadImageResultModel.fromJson(json.decode(response.body));

【讨论】:

能否请您检查一下我在上面做错了什么,更新了我的问题@omar-hatem 我缺少预期的标题,用对我有用的答案更新了我的问题:) 上传的图片已损坏 @SatishRaizada 我用一个实时工作代码更新了答案,希望这个有帮助 --> 更新问题请检查。我注意到存储在 blob 中的图像是实际图像类型,例如 image/jpg 或 image/png,但是当我使用应用程序上传时,有 multipart/form-data 是使用 http 上传类型的,我希望这会有所帮助不知何故【参考方案2】:

首先,将图像File 转换为Stream,因为数据将以流的形式推送到blob 容器。

Future uploadImage(File file) async 
    String fileName = file.path.split('/').last;
    _logger.info("File Path: " + fileName);

    String imageToken = "Get your own token";
    String containerName = "Blob container name";


    final fileBytes = file.readAsBytesSync();
    var streamData = Stream.fromIterable(fileBytes.map((e) => [e]));
    String uploadDestinationUrl = RollaConstants.HOST_IMAGE +
        "/$containerName" +
        "/$fileName" +
        imageToken;


    final Dio _dio = Dio();
    Response response;
    try 
      response = await _dio.put(uploadDestinationUrl,
          data: streamData,
          options: Options(headers: 
            Headers.contentLengthHeader: fileBytes.length,
            "x-ms-blob-type": "BlockBlob",
            "content-type": "image/jpeg"
          ));
     catch (error, stacktrace) 
      print("Exception occured: $error.response stackTrace: $stacktrace");
    
    print("Blob response: " + response.statusCode.toString());
  

【讨论】:

以上是关于使用 Flutter (iOS/Android) 将图像上传到 Azure blob的主要内容,如果未能解决你的问题,请参考以下文章

无法从 Flutter Web 读取 Firestore 中的数据(适用于 iOS 和 android)

Flutter专题Android Flutter入门笔记技术解析与项目实战

Flutter专题Android Flutter入门笔记技术解析与项目实战

Flutter Firebase——为 iOS、Android 和 Web 设置不同的部署目标

Flutter点击输入框外空白处隐藏输入法

flutter 介绍和环境搭建