简体   繁体   中英

Convert a UInt8List to Image in flutter/dart-ui

I have this scenario where I have to get a UInt8List from an image like that:

List stuff = image.toByteData().buffer.asUInt8List()

Do some manipulations and get back to a Image .

I've tried the following:

List stuff = image.toByteData().buffer.asUInt8List()
ui.decodeImageFromList(stuff, (image){
  // do stuff with image
});

But I keep getting this Exception:

E/flutter (10201): [ERROR:flutter/lib/ui/painting/codec.cc(97)] Failed decoding image. Data is either invalid, or it is encoded using an unsupported format.
E/flutter (10201): [ERROR:flutter/shell/common/shell.cc(186)] Dart Error: Unhandled exception:
...

Take notice that even without any changes in the List the exception is thrown. How can I make the list have a encodable format?

您可以使用下面给出的内存图像,用于直接字节渲染

child: Image.memory(Uint8List bytes);

You can use MemoryImage class to convert a Uint8List to image.

var _image = MemoryImage(image);

You can find more details about this classhere

ui.Image can turn itself into an RGBA bitmap (or PNG), but cannot convert itself back from a bitmap. (The reason for this is that there isn't any way to tell the image codec things like the color depth, geometry, etc.) The solution is to add a BMP file header onto the front of your bitmap, where you can describe those missing things, then pass that to instantiateImageCodec . See this answer , but note that in that case the bitmap in question had a strange packed color map. In your case of 32 bit RGBA, the header would be even simpler.

use this.

static Future<ui.Image> bytesToImage(Uint8List imgBytes) async{
    ui.Codec codec = await ui.instantiateImageCodec(imgBytes);
    ui.FrameInfo frame = await codec.getNextFrame();
    return frame.image;
  }

Here is a tested code for you.

    final directory = await getApplicationDocumentsDirectory();
    final pathOfImage = await File('${directory.path}/legendary.png').create();
    final Uint8List bytes = stuff.buffer.asUint8List();
    await pathOfImage.writeAsBytes(bytes);

final Uint8List bytes = stuff.buffer.asUint8List();

Here, stuff refers to the Uint8List that should be converted to an image.

this method worked for me, got the reference from another answer to a similar kind of problem at stackoverflow here

Future<ui.Image> loadImage(Uint8List img) async {
    final Completer<ui.Image> completer = Completer();
    ui.decodeImageFromList(img, (ui.Image img) {
      return completer.complete(img);
    });
    return completer.future;
  }

if anyone wants it as a file this worked for me you start by converting the Uint8list to a memory image , then save it on the phone then extract the file you're gonna need storage permissions tho

var _image = MemoryImage(UInt8ListData);
Directory appDocDirectory = await getApplicationDocumentsDirectory();

var file = await File(appDocDirectory.path + '/my_image.jpg')
        .writeAsBytes(_image.bytes);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM