Flutter AZURE BLOB IMAGE UPLOAD - 如何将使用移动相机拍摄的图像上传到 azure blob 存储

Posted

技术标签:

【中文标题】Flutter AZURE BLOB IMAGE UPLOAD - 如何将使用移动相机拍摄的图像上传到 azure blob 存储【英文标题】:Flutter AZURE BLOB IMAGE UPLOAD - How to upload image captured using mobile camera to azure blob storage 【发布时间】:2021-03-17 22:59:38 【问题描述】:

从昨天开始,我一直在努力尝试将使用移动相机从 ios/android 设备拍摄的图像上传到 azure blob 存储。

我可以上传文件,但由于某种原因它们已损坏无法打开上传的图像。

打开上传图片时请检查图片错误

我正在使用具有不同方法的 Flutter 包 http,所有这些都可以将图像文件上传到 azure blob 存储,但它会以某种方式损坏,我尝试将 ContentType 强制为 image/jpeg 但没有帮助。

这是我使用 http API 的代码 -

takePicture() async 
    final pickedFile = await picker.getImage(source: ImageSource.camera);

    setState(() 
      if (pickedFile != null) 
        _image = File(pickedFile.path);
        String fileName = basename(pickedFile.path);
        uploadFile(fileName, image);
       else 
        print('No image selected.');
      
    );
  

第一种方法-->

http.Response response = await http.put(
      uri,
      headers: 
        "Content-Type": 'image/jpeg',
        "X-MS-BLOB-TYPE": "BlockBlob",
      ,
      body: image.path,
    );
    print(response.statusCode);

使用第二个方法 -->

final data = image.readAsBytesSync();
  var dio = Dio();
  dio.options.headers['x-ms-blob-type'] = 'BlockBlob';
  dio.options.headers['Content-Type'] = 'image/jpeg';
  try 
    final response = await dio.put(
      '$url/$fileName?$token',
      data: data,
      onSendProgress: (int sent, int total) 
        if (total != -1) 
          print((sent / total * 100).toStringAsFixed(0) + "%");
        
      ,
    );
    print(response.statusCode);
   catch (e) 
    print(e);
  

接近第三个 -->

var request = new http.MultipartRequest("PUT", postUri);
      request.headers['X-MS-BLOB-TYPE'] = 'BlockBlob';
      request.headers['Content-Type'] = 'image/jpeg';
      request.files.add(
        new http.MultipartFile.fromBytes(
          'picture',
          await image.readAsBytes(),
        ),
      );
      request.send().then((response) 
        uploadResponse.add(response.statusCode);
      , onError: (err) 
        print(err);
      );

非常感谢您的帮助。

【问题讨论】:

我建议将Dio() 与此处列出的解决方案一起使用:***.com/questions/59293114/… 【参考方案1】:

不幸的是,多部分表单导致图像中断。我不知道它在天蓝色方面是如何工作的,因为关于分段上传的信息很少或根本没有,但由于分段形式,它显然被破坏了。我在 .net 核心应用程序中复制了该问题,并且每当我使用多部分表单数据上传图像时 - 它已损坏。当我使用简单的 ByteArrayContent 时 - 它可以工作。我找不到相当于 ByteArrayContent 的颤振,所以我现在迷路了:(@Jim 提到的包对我来说没用,因为我想给客户 sas url,所以他们有权在客户端上传图片。我做不想在 Flutter 应用中存储 Azure 存储帐户机密。

编辑。我找到了使用 Dio 包发送原始字节数据的解决方案。你也可以使用 http 包来做到这一点。

final dio = new Dio();
final fileBytes = file.readAsBytesSync();
var streamData = Stream.fromIterable(fileBytes.map((e) => [e]));

await dio.put(uploadDestinationUrl,
    data: streamData,
    options: Options(headers: 
      Headers.contentLengthHeader: fileBytes.length,
      "x-ms-blob-type": "BlockBlob",
      "content-type": "image/jpeg"
    ));

【讨论】:

嗨@Inclouds - 所以如果这是一个与原始问题的答案相关的新问题 - 请创建一个新问题,参考原始问题和答案以及什么不起作用它 - 这样你就可以得到答案。【参考方案2】:

如果你想在flutter应用中将图片上传到Azure Blob Storage,可以使用Dart Packageazblob来实现。包的使用方法请参考here。

例如

import 'package:image_picker/image_picker.dart';
import 'package:flutter/material.dart';
import 'package:azblob/azblob.dart';
import 'package:mime/mime.dart';

...
//use image_picker to get image

Future uploadImageToAzure(BuildContext context) async 
    try
      String fileName = basename(_imageFile.path);
      // read file as Uint8List 
      Uint8List content =  await  _imageFile.readAsBytes();
      var storage = AzureStorage.parse('<storage account connection string>');
      String container="image";
      // get the mine type of the file
      String contentType= lookupMimeType(fileName);
      await storage.putBlob('/$container/$fileName',bodyBytes: content,contentType: contentType,type: BlobType.BlockBlob);
      print("done");
     on AzureStorageException catch(ex)
      print(ex.message);
    catch(err)
      print(err);
    

【讨论】:

如果对你有用,可以accept it as an answer吗?

以上是关于Flutter AZURE BLOB IMAGE UPLOAD - 如何将使用移动相机拍摄的图像上传到 azure blob 存储的主要内容,如果未能解决你的问题,请参考以下文章

从 Azure 存储中流式传输 blob

文件流来自Azure存储的blob

获取 Azure Blob(图像)并 POST 到外部 API

如何将自定义响应标头添加到来自 azure blob 的响应?

Azure Powershell使用已有Image创建ARM非托管磁盘虚拟机

从 Azure Blob 存储文件名下载文件时出现的问题包含哈希 (#)