6

I have the network url of image and I need to get Uint8List. How can I convert it? I check answers in like question, but those ways don't work. How to get a Flutter Uint8List from a Network Image?

Andrey Molochko
  • 727
  • 1
  • 6
  • 21
  • what does "dont work" mean? – pskink Jan 24 '20 at 11:13
  • It means, that code is not actual for the latest version of Flutter. `var load = sunImage.load(val);` Method load requires two required parameters are NetworkImageKey and DecoderCallback – Andrey Molochko Jan 24 '20 at 11:22
  • `final DecoderCallback callback = (Uint8List bytes, {int cacheWidth, int cacheHeight}) { print(bytes.length); return instantiateImageCodec(bytes, targetWidth: cacheWidth, targetHeight: cacheHeight); }; ImageProvider provider = AssetImage('images/bg.png'); provider.obtainKey(createLocalImageConfiguration(context)).then((key) { provider.load(key, callback); });` i tested with `AssetImage` but it should work with any `ImageProvider` – pskink Jan 24 '20 at 17:11
  • nothing, `provider.load(key, callback)` is called – Andrey Molochko Jan 25 '20 at 09:02
  • And when must be called `print(bytes.length)`? – Andrey Molochko Jan 25 '20 at 09:14
  • when you get the encoded data, tried to run the code i posted (changing only 'images/bg.png'`)? – pskink Jan 25 '20 at 09:23
  • Yes I tried, and instead of asset image I did it `ImageProvider provider = CachedNetworkImageProvider("myUrl");`. After calling method `provider.load(key, callback);` nothing happens. – Andrey Molochko Jan 25 '20 at 09:36
  • i have no idea how you call it and what you mean by `"myUrl"` but i used: `ImageProvider provider = NetworkImage('https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png')` and it works just fine, it prints `got data: 3831 bytes` – pskink Jan 25 '20 at 09:45
  • I used `NetworkImage` instead CachedNetworkImage and I got bytes. I'll try to get image after it – Andrey Molochko Jan 25 '20 at 10:07
  • then call `provider.load(key, callback).addListener(listener)` - i mean add `.addListener(listener)` to the existing code – pskink Jan 25 '20 at 10:08
  • Thanks a lot. It works. You can copy your code and add to answer – Andrey Molochko Jan 27 '20 at 06:52
  • feel free to write a self answer ;-) – pskink Jan 27 '20 at 06:59
  • Isn't it simpler to use http get like this answer? https://stackoverflow.com/a/58310260/2942294 – syonip May 26 '20 at 08:31
  • @syonip The code looks simpler in that example, but some people can't run that code and they have different errors – Andrey Molochko May 26 '20 at 14:26

5 Answers5

14

Try this:

Uint8List bytes = (await NetworkAssetBundle(Uri.parse(url)).load(url))
    .buffer
    .asUint8List();
Alex
  • 1,457
  • 1
  • 13
  • 26
kaya
  • 724
  • 10
  • 24
  • 3
    Hi there, I'm trying to use your code in a bloc instead of downloading the image with an http get as on web the CORS policy doesn't allow it. and when on web I'm getting an `BlocError: Unsupported operation: Platform._version`. Any idea why? Many thanks. – Vincenzo Jul 14 '20 at 12:41
  • Hi @Vincenzo , I've tested on mobile not on web but if it's about cors policy you should consider using same domain, allow-origin header or jsonp. – kaya Jul 15 '20 at 09:59
  • hi @kaya, I actually solved it yesterday, I indeed had to define core header for my google storage bucket. now I can download them as I was. Many thanks for answering. – Vincenzo Jul 15 '20 at 11:20
6
Uint8List yourVar;
final DecoderCallback callback = (Uint8List bytes, {int cacheWidth, int cacheHeight}) {
        yourVar = bytes.buffer.asUint8List();
        return instantiateImageCodec(bytes, targetWidth: cacheWidth, targetHeight: cacheHeight);
      };
ImageProvider provider = NetworkImage(yourImageUrl);
    provider.obtainKey(createLocalImageConfiguration(context)).then((key) {
      provider.load(key, callback);
    });
Andrey Molochko
  • 727
  • 1
  • 6
  • 21
3

this did the trick for me:

import 'dart:typed_data';
import 'package:flutter/services.dart';

//Get the image from the URL and then convert it to Uint8List
Uint8List bytes = (await NetworkAssetBundle(Uri.parse('https://some_image_url.png'))
            .load('https://some_image_url.png'))
            .buffer
            .asUint8List();
1

This works on me (using flutter web) with a library file_saver.

Uri uri = Uri.parse(url);

Uint8List bytes = await readBytes(uri);
await FileSaver.instance.saveFile(filename, bytes, 'jpg',
    mimeType: MimeType.JPEG); // specify your vars
Sha-agi
  • 184
  • 2
  • 5
0

I'm having the same problem in Flutter web, I had to use the extended_image library, and I found inside your example that has a method that allows you to convert an ImageProvider to Bytes.

https://github.com/fluttercandies/extended_image/blob/master/example/lib/pages/simple/image_editor_demo.dart.

/// it may be failed, due to Cross-domain
Future<Uint8List> _loadNetwork(ExtendedNetworkImageProvider key) async {
  try {
    final Response response = await HttpClientHelper.get(Uri.parse(key.url),
        headers: key.headers,
        timeLimit: key.timeLimit,
        timeRetry: key.timeRetry,
        retries: key.retries,
        cancelToken: key.cancelToken);
    return response.bodyBytes;
  } on OperationCanceledError catch (_) {
    print('User cancel request ${key.url}.');
    return Future<Uint8List>.error(
        StateError('User cancel request ${key.url}.'));
  } catch (e) {
    return Future<Uint8List>.error(StateError('failed load ${key.url}. \n $e'));
  }
}