25

I would like to use a placeholder image file that I've added to my code as "assets/placeholder.png", but I'm getting a File not found error. This is how I'm doing it from the dartlang documentation...

var bytes = await new File('assets/placeholder.png').readAsBytes();
String base64 = CryptoUtils.bytesToBase64(bytes);

The bytes variable errors every time. How can I save the bytes of a locally saved image file?

Charles Jr
  • 8,333
  • 15
  • 53
  • 74

5 Answers5

41

With Flutter environment, you have to use AssetBundle if you want to access to your assets (https://flutter.io/assets-and-images/).

import 'package:flutter/services.dart' show rootBundle;


ByteData bytes = await rootBundle.load('assets/placeholder.png');
Hadrien Lejard
  • 5,644
  • 2
  • 21
  • 18
  • Any idea on how to then turn bytes into a BASE64 string? My CryptoUtils extension above isn't working. – Charles Jr Nov 06 '17 at 02:59
  • yes sorry, you should use BASE64 from "dart:convert", https://api.dartlang.org/stable/1.24.2/dart-convert/BASE64-constant.html – Hadrien Lejard Nov 06 '17 at 08:45
  • 4
    Please what if the file is from local storage? – X09 Mar 22 '18 at 15:21
  • 1
    As @X09 mentioned, this implementation doesnt work for loading images from local storage. I used this and first it works but if you load the image from a folder that has a space on the path, it wont work. So be careful – Mauricio Pastorini May 08 '19 at 15:33
19

In dart Uint8List is equal to byte[].

  1. Create one function and pass file path, It will return Bytes.

    Future<Uint8List> _readFileByte(String filePath) async {
        Uri myUri = Uri.parse(filePath);
        File audioFile = new File.fromUri(myUri);
        Uint8List bytes;
        await audioFile.readAsBytes().then((value) {
        bytes = Uint8List.fromList(value); 
        print('reading of bytes is completed');
      }).catchError((onError) {
          print('Exception Error while reading audio from path:' +
          onError.toString());
      });
      return bytes;
    }
    
  2. Now call the function in to get bytes of file.

    try{
      Uint8List audioByte;
      String myPath= 'MyPath/abc.png';
      _readFileByte(myPath).then((bytesData) {
        audioByte = bytesData;
      //do your task here 
      });
    } catch (e) {
       // if path invalid or not able to read
      print(e);
    }
    
  3. If you want base64String then use below code:

    String audioString = base64.encode(audioByte);

for base64 import 'dart:convert';

I hope it will help!

Wajid khan
  • 842
  • 9
  • 18
  • 4
    downvoted because the suggested solution adds only noise to what was essentially already correctly stated in the question (`File('...').readAsBytes()`), and what was added was not relevant to the question. for those taking this suggested answer as an example, to read and map (then) data from a Future, you can just assign the result of await ... then() directly to a variable, like `var result = await someFunc().then(...)`, so you don't need to declare the variable outside the scope of the callback, and then assign to it. – Bouke Versteegh Sep 07 '20 at 21:32
  • I declare the variable outside because if we can use it later before catch block. – Wajid khan Jan 29 '21 at 08:01
  • 2
    futures can return errors, which can be handled with `myFunc().then(processValue).catchError(handleError)`, see https://dart.dev/guides/libraries/futures-error-handling :-) – Bouke Versteegh Jan 29 '21 at 08:20
5
import 'dart:convert';
import 'package:flutter/services.dart';

...

ByteData byteData = await rootBundle.load('assets/image.png');

Uint8List bytes = byteData.buffer.asUint8List();

String base64Image = base64.encode(bytes);

Coala Jedi
  • 399
  • 3
  • 9
2

Here is an example to read file byte by byte:

import 'dart:io';

void main(List<String> arguments) {
  readFileByteByByte().then((done) {
    print('done');
  });
  print('waiting...');
  print('do something else while waiting...');
}

Future<bool> readFileByteByByte() async {
  //final fileName = 'C:\\code\\test\\file_test\\bin\\main.dart'; // use your image file name here
  final fileName = Platform.script.toFilePath(); //this will read this text file as an example
  final script = File(fileName);
  final file = await script.open(mode: FileMode.read);

  var byte;
  while (byte != -1) {
    byte = await file.readByte();
    if (byte == ';'.codeUnitAt(0)) { //check if byte is semicolon
      print(byte);
    }
  }
  await file.close();
  return (true);
}
live-love
  • 48,840
  • 22
  • 240
  • 204
2

if need read some bytes, use this

Future<Uint8List> readFileBytes(String path, int len) async {
    final File file = File(path);
    RandomAccessFile fileOpen = await file.open(mode: FileMode.read);

    int count = 0;
    List<int> bytes = [];
    int byte;

    while (byte != -1 && count < len) {
      byte = fileOpen.readByteSync();
      bytes.add(byte);
      count++;
    }

    await fileOpen.close();
    return Uint8List.fromList(bytes);
  }
Ali Bagheri
  • 3,068
  • 27
  • 28