How to convert Uint8List image to File Image for upload in flutter web
Asked Answered
S

4

49

I have have been able to pick a file from my computer and display in my flutter web app. I have a function(of type File) which takes a file and uploads it to the server. like so functionName(File imageToSend).

But when I try to send this image to the sever side, it gives me an error. Am doing the upload using the code below:

Uint8List uploadedImage;
File theChosenImg;
FileReader reader =  FileReader();
FileReader reader2 = FileReader();

filePicker() async {
InputElement uploadInput = FileUploadInputElement();
uploadInput.click();


uploadInput.onChange.listen((e) {
  // read file content as dataURL
  final files = uploadInput.files;
  if (files.length == 1) {
    final file = files[0];    

    reader.onLoadEnd.listen((e) {
                setState(() {
                  uploadedImage = reader.result;
                  theChosenImg = files[0];
                });
    });
    reader.readAsArrayBuffer(file);
    reader2.readAsDataUrl(file);
  }
});
}

when I use the variable uploadedImage the error is Expected a value of type 'File', but got one of type 'String' then I decided to use theChosenImg from theChosenImg = files[0];, this also tell me that the datatypes mismatch.

Is it possible for me to convert the Uint8List datatype to File?

UPDATED WITH CODE

import 'dart:typed_data';
import 'dart:html';
import 'dart:ui' as ui;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:web_image_upload/impUp.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class FrontUi extends StatefulWidget {
  @override
  _FrontUiState createState() => _FrontUiState();
}

class _FrontUiState extends State<FrontUi> {

Uint8List uploadedImage;
File theChosenImg;
String dispText = 'Uploaded image should shwo here.';
FileReader reader2 = FileReader();

_startFilePicker() async {
InputElement uploadInput = FileUploadInputElement();
uploadInput.click();


uploadInput.onChange.listen((e) {
  // read file content as dataURL
  final files = uploadInput.files;
  if (files.length == 1) {
    final file = files[0];
    FileReader reader =  FileReader();

    reader.onLoadEnd.listen((e) {
                setState(() {
                  uploadedImage = reader.result;
                  theChosenImg = files[0];
                });
    });
    reader.readAsArrayBuffer(file);
    reader2.readAsDataUrl(file);
  }
});
}

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ListView(
          children: <Widget>[
            Column(
              children: <Widget>[
                SizedBox(
                  height: 30,
                ),
                Container(
                  height: 500,
                  width: 800,
                  child: Center(
                    child: uploadedImage == null
                ? Container(
                    child: Text(dispText),
                  )
                : Container(
                    child: Image.memory(uploadedImage),
                  ),
                  ),
                ),
            SizedBox(height: 20,),                
                CupertinoButton(
                  color: Colors.green,
                  child: Text("Choose"),
                  onPressed: (){
                    _startFilePicker();
                  },
                ),

            SizedBox(height: 50,),
             CupertinoButton(
              color: Colors.green,
              child: Text("Upload"),
              onPressed: (){
                PhotoCls().upload(reader2.result);
              },
            ),



              ],
            ),



          ],
        ),
      ),

    );
  }
}

Class with The MEDTHOD WHICH SENDS THE IMAGE

import 'dart:io';
import 'package:path/path.dart';
import 'package:async/async.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';



  class PhotoCls {
 String phpEndPoint = "http://IPv4 address/testlocalhost/uploadPicture.php";


upload(File imageFile) async {    
      // open a bytestream
      var stream = new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
      // get file length
      var length = await imageFile.length();

      // string to uri
      var uri = Uri.parse(phpEndPoint);

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

      // multipart that takes file
      var multipartFile = new http.MultipartFile('file', stream, length,
          filename: basename(imageFile.path));

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

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

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



  }
Shaer answered 10/11, 2019 at 23:46 Comment(3)
Could you post your code for file upload..! Along with your import statements.They
@AbhilashChandran updated with codeShaer
I am sure you cannot use dart:io library in the context of flutter_web. Try to use the File class from dart:html. The file object returned by FileUploadInputElement is of type File from dart:html library.They
H
79

Include this package https://pub.dev/packages/path_provider

import 'package:path_provider/path_provider.dart';
import 'dart:io';

Uint8List imageInUnit8List = // store unit8List image here ;
final tempDir = await getTemporaryDirectory();
File file = await File('${tempDir.path}/image.png').create();
file.writeAsBytesSync(imageInUnit8List);

// -.-.-.-    Unit8List ->  File      -.-.-.-  
Homeopathist answered 15/11, 2021 at 11:49 Comment(8)
This is the best answer yet....another under estimated answer here to...Pneumato
path_provider don't have web support yet.Impolite
Has anyone got web solution to these?Arnaud
does it support for animated webp files? i.e. gif to webp(anim)Fowler
This works in windows! The best answer!Holinshed
This should be the accepted answer, other creates a file with no propertiesTouchback
working fine thanks, for poeple assckong about upload : request.files.add( MultipartFile.fromBytes("formFile", await fileParrsed.readAsBytes(),filename: 'name.png',));Campball
THIS DOES NOT WORK FOR WEBUndesirable
F
75
File.fromRawPath(Uint8List uint8List);
Friede answered 18/1, 2020 at 9:34 Comment(4)
dart io is not supported on the webMarkley
file does not length issue for this answer. https://mcmap.net/q/349498/-how-to-convert-uint8list-image-to-file-image-for-upload-in-flutter-web worked for me.Fewer
This caused a crash for me. fromRawPath couldn't parse a Uint8List from a JPG image.Chesna
Could use further expansion like the next one belowJockstrap
J
9

I tried to generate one code who can support both device and web together.

Because File.fromRawPath() uses dart:io and its not working for web.

This is my solution :

Uint8List imageCroppedBytes;

First, I picked my image by image_picker then cropped by extended_image .

Somewhere in my code after cropping I encoded cropped byte file to jpg.

imageCroppedBytes = Image.encodeJpg(src , quality: 80);

Then :

var image = http.MultipartFile.fromBytes('image', imageCroppedBytes ,filename: 'profileImage.jpg');
request.files.add(image);
await request.send().then((value) async {
    if(value.statusCode == 200) {
      Do Something ...
    }
});

In my case I have a NodeJs back with Multer to get the file and save it.

Editted :

import 'package:image/image.dart' as Image;

More code for help :

var data = editorKey.currentState.rawImageData;
Image.Image src = Image.decodeImage(data);
src = Image.copyCrop(src, cropRect.left.toInt(), cropRect.top.toInt(),
                          cropRect.width.toInt(), cropRect.height.toInt());
if(src.width > 300) {
src = Image.copyResize(src,width: 300 , height: 300);
}
setState(() {
   imageCroppedBytes = Image.encodeJpg(src , quality: 80);
   imagePicked = false;
   imageCropped = true;
});
Judd answered 20/3, 2021 at 15:24 Comment(3)
Do you have a working repository? This answer is way to sparse and given there are some apps still not migrated to null safety, you might want to put some reference link to a repository or docs. This is the answer that I know will work for me, but I'm unable to figure out where to find the .encodeJpg function, because it does not belong to ImagePicker, Image or ExtendedImage. Will appreciate some help!Strung
Dear @rshrc actually I don't have any open repository for this, but I'll edit more to helpJudd
Thanks you so much!!Strung
A
-2

With Flutter Web use:

 Uint8List imageData;
 // Stream.fromIterable(imageData.map((e) => [e]));
 final response = await Dio().put(url,
      data: Stream.fromIterable(data.map((e) => [e])),
      options: Options(
          headers: {
            Headers.contentLengthHeader: len,
            Headers.contentTypeHeader: mime,
          } // set content-length
      ));
Abeyance answered 19/7, 2023 at 2:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.