1

目前我有一个 Uint8List,格式为 [R,G,B,R,G,B,...] 用于图像的所有像素。当然,我有它的宽度和高度。

decodeImageFromPixels在搜索时发现但它只需要 RGBA/BGRA 格式。我将我的像素图从 RGB 转换为 RGBA,这个函数工作正常。

但是,我的代码现在看起来像这样:

Uint8List rawPixel = raw.value.asTypedList(w * h * channel);
List<int> rgba = [];
for (int i = 0; i < rawPixel.length; i++) {
  rgba.add(rawPixel[i]);
    if ((i + 1) % 3 == 0) {
      rgba.add(0);
    }
}

Uint8List rgbaList = Uint8List.fromList(rgba);

Completer<Image> c = Completer<Image>();
decodeImageFromPixels(rgbaList, w, h, PixelFormat.rgba8888, (Image img) {
  c.complete(img);
});

我必须创建一个新列表(浪费空间)并遍历整个列表(浪费时间)。

在我看来这太低效了,有什么办法可以让它更优雅吗?喜欢添加一个新的PixelFormat.rgb888

提前致谢。

4

1 回答 1

0

您可能会发现此循环更快,因为它不会一直附加到列表然后在最后复制它。

  final rawPixel = raw.value.asTypedList(w * h * channel);
  final rgbaList = Uint8List(w * h + 4); // create the Uint8List directly as we know the width and height

  for (var i = 0; i < w * h; i++) {
    final rgbOffset = i * 3;
    final rgbaOffset = i * 4;
    rgbaList[rgbaOffset] = rawPixel[rgbOffset]; // red
    rgbaList[rgbaOffset + 1] = rawPixel[rgbOffset + 1]; // green
    rgbaList[rgbaOffset + 2] = rawPixel[rgbOffset + 2]; // blue
    rgbaList[rgbaOffset + 3] = 255; // a
  }

另一种方法是通过调整此答案(尽管它会更简单,因为没有调色板)并将该位图传递给该代码,因此可以在数组前面加上 BMP 标头,instantiateImageCodec因为该代码可能已针对解析位图进行了高度优化。

于 2022-01-14T10:50:35.143 回答