Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter AZURE BLOB IMAGE UPLOAD - How to upload image captured using mobile camera to azure blob storage

I have been working for few since yesterday to try upload an image to azure blob storage taken using mobile camera form iOS/Android device.

I am able to upload the files but for some reason they being corrupted not able to open the image uploaded.

Please check the image error while opening the uploaded image

Valid XHTML

I am using flutter package http with different approach all work in uploading image file to azure blob store but it gets corrupted somehow , I tried forcing the ContentType to image/jpeg but no help.

Here is code I am using an 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.');
      }
    });
  }

First approach -->

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

Using Approach second -->

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);
  }

Approach third -->

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);
      });

Help here is much appreciated.

like image 706
Jerry Patel Avatar asked Oct 23 '25 09:10

Jerry Patel


2 Answers

If you want to upload the image to Azure Blob Storage in the flutter application, you can use the Dart Package azblob to implement it. Regarding how to use the package, please refer to here.

For example

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);
    }

enter image description here enter image description here

like image 172
Jim Xu Avatar answered Oct 25 '25 01:10

Jim Xu


Unfortunately, the multipart form is causing break of image. I don't know how it works on azure side, because there is little or no information about multipart uploads, but it's clearly broken because of multipart form. I replicated the problem in .net core application and whenever i am using multipart form data to upload image - it is broken. When i am using simple ByteArrayContent - it works. I couldn't find flutter equivalent to ByteArrayContent, so i am lost now :( The package mentioned by @Jim is useless for me, because i want to give clients sas url, so they have permission to upload image on client side. I do not want to store azure storage account secrets in flutter app.

EDIT. I found the solution to send raw byte data with Dio package. You can do that also with http package.

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"
    }));
like image 38
Inclouds Avatar answered Oct 25 '25 00:10

Inclouds