Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use rootBundle in flutter to load images?

I use image plugin (image: ^2.0.4) so I can write something on to the image and later save it new image to device or send via mail. I try to load image using "new File" but got error on Flutter. I ask and search and got a hint that I can use rootBundle to load image in Flutter. I did, and I got this below error.

[ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception: Unable to load asset: packages/myAppName/assets/images/ReceiptRaw_1.jpg

The plugin works when I create a simple dart console app, but couldn't load using flutter. Any help please,

This is the Flutter Code:

    Future<bool> makeReceiptImage() async {

// UPDATE ****************************************

      // load the receipt jpeg
  var imageData = await rootBundle.load('packages/myAppName/dekonts/ReceiptRaw_1.jpg');
  print("imageData: $imageData"); // Prints as imageData: Instance of 
'_ByteDataView'

// UPDATE ****************************************

  Image _receiptImage = await decodeImage(new File(imageData).readAsBytesSync());

      drawString(_receiptImage, arial_48, 440, 30, “Customer Name”, color: 0xFF000000); 

      // Write it to disk as a different jpeg 
      var new_jpeg = await encodeJpg(_receiptImage); 
      String newImagePath = await rootBundle.loadString('packages/myAppName/assets/images/ReceiptRaw_2.jpg'); 
      await new File(‘$newImagePath’).writeAsBytesSync(new_jpeg); 
    }

This is the Dart Console Code:

import 'dart:io';
import 'dart:convert';
import 'dart:async';
import 'package:image/image.dart';

void main() async {
  // load the receipt jpeg
  String mImagePath = 'images/ReceiptRaw_1.jpg';
  Image _receiptImage = decodeImage(new File(mImagePath).readAsBytesSync());
  drawString(_receiptImage, arial_48, 440, 30, “Customer Name”, color: 0xFF000000);

  // Write it to disk as a different jpeg
  var new_jpeg = encodeJpg(_receiptImage);
  new File('images/ReceiptRaw_1.jpg').writeAsBytesSync(new_jpeg);
}

Update-1: When I use below code I get en error as:

Error detected in pubspec.yaml: No file or variants found for asset: packages/myAppName/assets/images/ReceiptRaw_1.jpg

 String imageData = await rootBundle.loadString('packages/myAppName/assets/images/ReceiptRaw_1.jpg');
  Image _receiptImage = await decodeImage(new File(imageData).readAsBytesSync());

Update-2: if I use rootBundle.load I got below error.

Error: A value of type 'dart.typed_data::ByteData' can't be assigned to a variable of type 'dart.core::String'.

var imageData = await rootBundle.load('packages/myAppName/assets/images/ReceiptRaw_1.jpg');
  Image _receiptImage = await decodeImage(new File(imageData).readAsBytesSync());

New Update:

Step 1: Move to ReceiptRaw_1.jpg into lib/dekonts/ folder

Change to:

assets:
  - packages/myAppName/dekonts/ReceiptRaw_1.jpg

Change to:

var imageData = await rootBundle.load('packages/myAppName/dekonts/ReceiptRaw_1.jpg');
print("imageData: $imageData"); 

Result: Prints as

imageData: Instance of '_ByteDataView'

Step 2: Move to /lib/assets/images/ReceiptRaw_1.jpg folder

Change to:

assets:
  - packages/myAppName/lib/assets/images/ReceiptRaw_1.jpg

Change to:

var imageData = await rootBundle.load('packages/myAppName/lib/assets/images/ReceiptRaw_1.jpg');
print("imageData: $imageData"); 

Result: Got Error as:

Resolving dependencies... Running 'gradlew assembleDebug'... Error detected in pubspec.yaml: No file or variants found for asset: packages/myAppName/lib/assets/images/ReceiptRaw_1.jpg

Update:

/// To include, say the first image, the pubspec.yaml of the app should
/// specify it in the assets section:
///
/// assets: /// - packages/fancy_backgrounds/backgrounds/background1.png ///
/// The lib/ is implied, so it should not be included in the asset path.

like image 287
Nick Avatar asked Jul 31 '18 08:07

Nick


People also ask

How do I use rootBundle in Flutter?

To add resources to the rootBundle for your application, add them to the assets subsection of the flutter section of your application's pubspec. yaml manifest. Rather than using rootBundle directly, consider obtaining the AssetBundle for the current BuildContext using DefaultAssetBundle.

How do I quickly load asset images in Flutter?

We have a simple yet useful method in Flutter which we can use to load our asset images much faster — precacheImage()! This method prefetches the image into the image cache and then whenever the image is used, it will be loaded much faster.

How do I load an image from URL Flutter?

Display Image from URL in Flutter – Image.network() In Flutter, you can display an image from different possible sources. To display an image from URL, you may use Image.network() constructor of Image class.


2 Answers

The files of pub dependencies are not available as files. They are contained in an archive file.

Add the image to assets in pubspec.yaml

flutter:
  assets:
    - packages/myAppName/assets/images/ReceiptRaw_1.jpg

then load it with

var imageData = await rootBundle.load('packages/myAppName/assets/images/ReceiptRaw_1.jpg');

For this to work the file ReceiptRaw_1.jpg needs to be in

myAppName/lib/assets/images/ReceiptRaw_1.jpg

Where the lib/ part is mandatory.

like image 64
Günter Zöchbauer Avatar answered Sep 20 '22 20:09

Günter Zöchbauer


With @Günter Zöchbauer help, I finally made it. My small contribution to Stack Overflow members.

// TODO: 1 - LOAD EVERYTHING

  Future _loadEverything() async {
    await _requestAppDocumentsDirectory();   // TODO: 2 - GET APP DOCUMENTS DIRECTORY
    _dekontExist = await makeReceiptImage(); // TODO: 3 - MAKE A RECEIPT

    // Show the writen image
    if (_dekontExist == true) {
      setState(() {
        newDekontImage = _appDocumentsDirectory + "/" + widget._currentUserReceiptNo + ".jpg";
        imageOkay = true; // FOR - 4 - MAIN WIDGET BUILD
      });
    }
  }

// TODO: 2 - GET APP DOCUMENTS DIRECTORY

Future _requestAppDocumentsDirectory() async {
  // I choose temp dir because I don’t want to write twice same Receipt
  // Also when user close the app it will destroys the images
  final _directory =
      await getTemporaryDirectory(); //getApplicationDocumentsDirectory();
  setState(() {
    _appDocumentsDirectory = _directory.path;
  });
}

// TODO: 3 - MAKE A RECEIPT

Future<bool> makeReceiptImage() async {

  // I use this as a template:
  // 'packages/mayApp/assets/images/CapitalReceipt.jpg'  

  ByteData imageData = await rootBundle.load('packages/mayApp/assets/images/CapitalReceipt.jpg');
  List<int> bytes = Uint8List.view(imageData.buffer);
  Image _receiptImage = decodeImage(bytes);

  // TODO: WRITE ON TO THE IMAGE
  drawString(_receiptImage, arial_48, 440, 30, “Customer Receipt - Customer Name”, color: 0xFF000000);


  // Write it to disk as a different jpeg
    var new_jpeg = await encodeJpg(_receiptImage);
    String newDekontImage = _appDocumentsDirectory + "/" + "${_currentUserReceiptNo}" + ".jpg";
    await new File(newDekontImage).writeAsBytesSync(new_jpeg);

  return true;
}

// TODO: 4 - MAIN WIDGET BUILD

  @override
  Widget build(BuildContext context) {
    capitalHeight = MediaQuery.of(context).size.height;
    capitalWidth = MediaQuery.of(context).size.width;

    if (imageOkay == true) {
      return new Scaffold(
        resizeToAvoidBottomPadding: true,
        appBar: new AppBar(
          title: new Text("Customer Receipt"),
          backgroundColor: const Color(0xFF7CB342),
          elevation: 0.0,
          actions: <Widget>[
            new Container(
              padding: EdgeInsets.only(right: 10.0),
              child: new Icon(Icons.mail),
            )
          ],
        ),
        body: new Column(
          children: <Widget>[
            new Padding(
              padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
              child: new Center(
                child: new Container(
                  width: capitalWidth,
                  height: capitalHeight / 2.3,
                  color: Colors.black54, //capitalLightGreen,
                  child: new Container(
                    width: capitalWidth - 20.0,
                    height: capitalHeight / 2.3,
                    child: Image.file(File('$newDekontImage')),
                  )
                ),
              )
            ),
          ],
        ),
      );
    } else {
      return new Scaffold(
          resizeToAvoidBottomPadding: true,
          appBar: new AppBar(
            title: new Text("Customer Receipt"),
            backgroundColor: const Color(0xFF7CB342),
            elevation: 0.0,
            actions: <Widget>[
              new Container(
                padding: EdgeInsets.only(right: 10.0),
                child: new Icon(Icons.mail),
              )
            ],
          ),
          body: new Center(
            child: new CircularProgressIndicator(),
          ));
    }
  }
like image 24
Nick Avatar answered Sep 20 '22 20:09

Nick