44

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



  }
Norbert
  • 6,874
  • 14
  • 40
  • 65
  • Could you post your code for file upload..! Along with your import statements. – Abhilash Chandran Nov 12 '19 at 15:40
  • @AbhilashChandran updated with code – Norbert Nov 12 '19 at 17:22
  • 1
    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](https://api.dartlang.org/stable/2.6.1/dart-html/File-class.html) from `dart:html` library. – Abhilash Chandran Nov 12 '19 at 17:40

4 Answers4

66
File.fromRawPath(Uint8List uint8List);
Nathan Mersha
  • 749
  • 5
  • 6
59

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      -.-.-.-  
Muhammad Tameem Rafay
  • 3,602
  • 2
  • 21
  • 32
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;
});
Ali Esfandiari
  • 316
  • 4
  • 13
  • 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! – DeprecatedAPI Mar 23 '21 at 16:14
  • Dear @rshrc actually I don't have any open repository for this, but I'll edit more to help – Ali Esfandiari Mar 26 '21 at 11:09
  • Thanks you so much!! – DeprecatedAPI Mar 26 '21 at 16:00
0

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
      ));
Doan Bui
  • 3,572
  • 25
  • 36