Search code examples
dartflutter

How to convert asset image to File?


Is there a way to use an asset image as a File. I need a File so it can be used for testing it over the internet using http. I've tried some answers from Stackoverflow.com (How to load images with image.file) but get an error 'Cannot open file, (OS Error: No such file or directory, errno = 2)'. The attached code line also gives an error.

File f = File('images/myImage.jpg');

RaisedButton(
   onPressed: ()=> showDialog(
     context: context,
     builder: (_) => Container(child: Image.file(f),)),
   child: Text('Show Image'),)

Using Image.memory widget(works)

Future<Null> myGetByte() async {
    _byteData = await rootBundle.load('images/myImage.jpg');
  }

  /// called inside build function
  Future<File> fileByte = myGetByte();

 /// Show Image
 Container(child: fileByte != null
 ? Image.memory(_byteData.buffer.asUint8List(_byteData.offsetInBytes, _ 
 byteData.lengthInBytes))
 : Text('No Image File'))),

Solution

  • You can access the byte data via rootBundle. Then, you can save it to the device's temporary directory which is obtained by path_provider (you need to add it as a dependency).

    import 'dart:async';
    import 'dart:io';
    
    import 'package:flutter/services.dart' show rootBundle;
    import 'package:path_provider/path_provider.dart';
    
    Future<File> getImageFileFromAssets(String path) async {
      final byteData = await rootBundle.load('assets/$path');
    
      final file = File('${(await getTemporaryDirectory()).path}/$path');
      await file.create(recursive: true);
      await file.writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
    
      return file;
    }
    

    In your example, you would call this function like this:

    File f = await getImageFileFromAssets('images/myImage.jpg');
    

    For more information on writing the byte data, check out this answer.

    You will need to await the Future and in order to do that, make the function async:

    RaisedButton(
       onPressed: () async => showDialog(
         context: context,
         builder: (_) => Container(child: Image.file(await getImageFileFromAssets('images/myImage.jpg')))),
       child: Text('Show Image'));