How to convert image to uint8list in flutter without using async?
Asked Answered
J

5

13

PdfImage requires Uint8List as param but I have ImageProvider. So how can we convert image to uint8list in flutter?

var imageProvider = AssetImage('assets/test.jpg');

final image = PdfImage(
  pdf.document,
  image:???, /// Uint8List required
  width: img.width,
  height: img.height,
);

Using FutureBuilder: enter image description here

Juna answered 30/7, 2019 at 4:40 Comment(12)
simply use rootBundle.load(), as it returns a Future you have to use then method after load completesDeckhand
Your answer is correct in normal case. But in my case it little bit different. I Have to render image in pdf. So, I need to work without async func in stateless widgetJuna
where did i say async? i said: use then methodDeckhand
I have to use this in build function that return the stateless widget. So, how to do this?Juna
Nope unable to use it when using the packages: 'package:flutter/widgets.dart' as fw; and 'package:pdf/widgets.dart'Juna
@Deckhand Please check the about screenshot.Juna
Let us continue this discussion in chat.Juna
I have to use this package: import 'package:pdf/widgets.dart' as pw; ERROR: The function 'FutureBuilder' isn't defined. Note: I think the FutureBuilder may not till build in the pdf-package.Juna
I can't use the material package because I am working on dart_pdf library.Juna
ok, first of all, what do you want to use with PdfImage? what do you need it for? what does it have to do with your custom StatelessWidget? is it used by its build() method? - if you just want to save your pdf file then do not mix pdf widgets and flutter widgetsDeckhand
First, I want to split the child widget to smaller ones. Reason, the child widget container contains the dynamic image list that has to render in pdf. Note: I had already chat with the package builder of dart_pdf. He mentioned it is not possible to create the image without using async.Juna
Child widget container contains the dynamic image list that has to render in pdf. I just want to render the image in pdf and download. Sorry, If I didn't get your question.Juna
S
13

Use rootBundle.load()

(await rootBundle.load(/*YOUR IMAGE PATH HERE*/)).buffer.asUint8List()

UPDATE

As load() is an async operation, you need to wait until the data is fully loaded. Try substituting the UI with some loading indicator until then.

ByteData imageData;

@override
void initState() {
  rootBundle.load('assets/test.jpg')
    .then((data) => setState(() => this.imageData = data));
}

@override
Widget build(BuildContext context) {
  if (imageData == null) {
    return Center(child: CircularProgressIndicator());
  }

  final image = PdfImage(
    pdf.document,
    image: imageData.buffer.asUint8List(),
    width: img.width,
    height: img.height,
  );

  ...
}
Stereophonic answered 30/7, 2019 at 4:42 Comment(5)
The await expression can only be used in an asynchronous function. Try marking the function body with either 'async' or 'async*' ??Juna
Is is possible to convert without async call?Juna
Your answer is correct in normal case. But in my case it little bit different. I Have to render image in pdf. So, I need to work without async func in stateless widget.Juna
Sorry this is the only way I knowStereophonic
Used packages: 'package:flutter/widgets.dart' as fw; and 'package:pdf/widgets.dart';Juna
S
4

I tried different solutions to convert image to UInt8List and finally found one Solution. It worked for me.

XFile? image = await imagePicker.pickImage(
     source: ImageSource.gallery,
); // Upload file from gallery

final bytes = await image!.readAsBytes(); // Converts the file to UInt8List

for the output, i used MemoryImage

MemoryImage(bytes!);

Stipitate answered 3/8, 2022 at 13:5 Comment(0)
M
3

in Flutter, attaching local image to pdf file. Actually It's a simple solution to add our local image to pdf file. just copy paste the following code and try

final ByteData bytes = await rootBundle.load('assets/logo.jpg');
final Uint8List list = bytes.buffer.asUint8List();

final image = PdfImage.file(
  pdf.document,
  bytes: list,
);

pdf.addPage(pw.Page(build: (pw.Context context) {
  return pw.Center(
    child: pw.Image(image),
  ); // Center
}));
Mohur answered 12/4, 2020 at 4:59 Comment(0)
S
0

You could split initState into two if you prefer:

@override
void initState() {
  loadAsset('test.jpg');
}

void loadAsset(string name) async {
  var data = await rootBundle.load('assets/$name');
  setState(() => this.imageData = data);
}

Note that this will cause build() to run an extra time but I find it easier on the eye. With Michael's circular Indicator, this is a harmless extra cycle.

Serrano answered 30/7, 2019 at 7:8 Comment(0)
H
0

The short answer: "You can't".

But this package contains all possible image converters with sync and async. Code example with sync:

final r = source.widgetImageSync;
// or
... = source.uiImageSync;
... = source.uint8ListSync;
... = source.imageProviderSync;
Husted answered 26/3 at 16:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.