Dart 使用';ui.decodeImageFromList';显示从字节列表创建的图像的步骤

Dart 使用';ui.decodeImageFromList';显示从字节列表创建的图像的步骤,dart,flutter,Dart,Flutter,我已经搜索了一段时间,了解如何创建一个有状态图像,该图像可以从字节数组(或简单的十六进制颜色值列表)创建。我在dart的ui库中遇到了这个看似有用的函数 有人能举例说明如何使用它吗?你能决定每像素多少位吗 提前感谢。decodeImageFromList只是实例化图像编解码器的一个方便包装,它可以解码少数受支持的图像格式之一(JPEG、PNG、GIF、动画GIF、WebP、动画WebP、BMP和WBMP)。令人惊讶的是,目前还没有一种方法可以传递原始位图。但是,BMP文件格式基本上是固定在位图前

我已经搜索了一段时间,了解如何创建一个有状态图像,该图像可以从字节数组(或简单的十六进制颜色值列表)创建。我在dart的ui库中遇到了这个看似有用的函数

有人能举例说明如何使用它吗?你能决定每像素多少位吗


提前感谢。

decodeImageFromList
只是
实例化图像编解码器
的一个方便包装,它可以解码少数受支持的图像格式之一(JPEG、PNG、GIF、动画GIF、WebP、动画WebP、BMP和WBMP)。令人惊讶的是,目前还没有一种方法可以传递原始位图。但是,BMP文件格式基本上是固定在位图前面的简单标题(可以是RGB、RGBA或使用索引颜色贴图)。标题字段告诉解码器宽度、高度、每像素位数、像素格式等

在内存中构造BMP头、附加位图并将其传递给上述任一函数都非常容易

这里有一个完整的例子。请注意,从RGB332到ARGB的映射有点不正确。实际上,您应该使用256个成员的查找表。循环为RGB322字节的256个可能值生成256个近似ARGB值

如果您希望在画布上绘制,请使用
instantialeimagecodec
而不是
Image.memory
小部件

import 'dart:math';
import 'dart:typed_data';

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'BMP Demo',
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Uint8List bmp;
  BMP332Header header;
  Random r = Random();

  @override
  void initState() {
    super.initState();
    header = BMP332Header(100, 100);
    bmp = header.appendBitmap(
        Uint8List.fromList(List<int>.generate(10000, (i) => r.nextInt(255))));
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Bitmap'),
      ),
      body: Center(
        child: Image.memory(bmp),
      ),
    );
  }
}

class BMP332Header {
  int _width; // NOTE: width must be multiple of 4 as no account is made for bitmap padding
  int _height;

  Uint8List _bmp;
  int _totalHeaderSize;

  BMP332Header(this._width, this._height) : assert(_width & 3 == 0) {
    int baseHeaderSize = 54;
    _totalHeaderSize = baseHeaderSize + 1024; // base + color map
    int fileLength = _totalHeaderSize + _width * _height; // header + bitmap
    _bmp = new Uint8List(fileLength);
    ByteData bd = _bmp.buffer.asByteData();
    bd.setUint8(0, 0x42);
    bd.setUint8(1, 0x4d);
    bd.setUint32(2, fileLength, Endian.little); // file length
    bd.setUint32(10, _totalHeaderSize, Endian.little); // start of the bitmap
    bd.setUint32(14, 40, Endian.little); // info header size
    bd.setUint32(18, _width, Endian.little);
    bd.setUint32(22, _height, Endian.little);
    bd.setUint16(26, 1, Endian.little); // planes
    bd.setUint32(28, 8, Endian.little); // bpp
    bd.setUint32(30, 0, Endian.little); // compression
    bd.setUint32(34, _width * _height, Endian.little); // bitmap size
    // leave everything else as zero

    // there are 256 possible variations of pixel
    // build the indexed color map that maps from packed byte to RGBA32
    // better still, create a lookup table see: http://unwind.se/bgr233/
    for (int rgb = 0; rgb < 256; rgb++) {
      int offset = baseHeaderSize + rgb * 4;

      int red = rgb & 0xe0;
      int green = rgb << 3 & 0xe0;
      int blue = rgb & 6 & 0xc0;

      bd.setUint8(offset + 3, 255); // A
      bd.setUint8(offset + 2, red); // R
      bd.setUint8(offset + 1, green); // G
      bd.setUint8(offset, blue); // B
    }
  }

  /// Insert the provided bitmap after the header and return the whole BMP
  Uint8List appendBitmap(Uint8List bitmap) {
    int size = _width * _height;
    assert(bitmap.length == size);
    _bmp.setRange(_totalHeaderSize, _totalHeaderSize + size, bitmap);
    return _bmp;
  }

}
import'dart:math';
导入“dart:键入的_数据”;
进口“包装:颤振/材料.省道”;
void main()=>runApp(新的MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回新材料PP(
标题:“BMP演示”,
主页:新建MyHomePage(),
);
}
}
类MyHomePage扩展StatefulWidget{
@凌驾
_MyHomePageState createState()=>new_MyHomePageState();
}
类_MyHomePageState扩展状态{
Uint8List-bmp;
BMP332割台;
随机r=随机();
@凌驾
void initState(){
super.initState();
收割台=BMP332收割台(100100);
bmp=header.append位图(
Uint8List.fromList(List.generate(10000,(i)=>r.nextInt(255));
}
@凌驾
小部件构建(构建上下文){
归还新脚手架(
appBar:新的appBar(
标题:新文本(“位图”),
),
正文:中(
子:Image.memory(bmp),
),
);
}
}
类bmp332头{
int _width;//注意:宽度必须是4的倍数,因为没有考虑位图填充
内部高度;
Uint8List\u bmp;
int_totalHeaderSize;
BMP332Header(this.\u width,this.\u height):断言(\u width&3==0){
int baseHeaderSize=54;
_totalHeaderSize=baseHeaderSize+1024;//基本+颜色贴图
int fileLength=\u totalHeaderSize+\u width*\u height;//头+位图
_bmp=新的UINT8列表(文件长度);
ByteData bd=_bmp.buffer.asByteData();
bd.setUint8(0,0x42);
bd.setUint8(1,0x4d);
bd.setUint32(2,fileLength,Endian.little);//文件长度
bd.setUint32(10,_totalHeaderSize,Endian.little);//位图的开始
bd.setUint32(14,40,Endian.little);//信息头大小
bd.setUint32(18,宽度,尾端小);
bd.setUint32(22,高度,尾端小);
bd.setUint16(26,1,Endian.little);//平面
bd.setUint32(28,8,Endian.little);//bpp
bd.setUint32(30,0,Endian.little);//压缩
bd.setUint32(34,_-width*_-height,Endian.little);//位图大小
//其他一切都保持为零
//像素有256种可能的变化
//构建从压缩字节映射到RGBA32的索引颜色映射
//更好的方法是创建查找表,请参见:http://unwind.se/bgr233/
用于(int rgb=0;rgb<256;rgb++){
int offset=baseHeaderSize+rgb*4;
int red=rgb&0xe0;

int green=rgb可能对颤振插件有帮助 我通过以下方式从指纹设备转换java位图:

ByteArrayOutputStream stream = new ByteArrayOutputStream();
fingerBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
fingerBitmap.recycle();
然后在飞镖我只是用

Uint8List fingerImages;

  void mapFingerImage(dynamic imageBytes) {
    setState(() {
      fingerImages = imageBytes;
    });
  }
    Image.memory(fingerImages,
                  width: 100,
                  height: 100,
                   fit: BoxFit.contain,)

当您在ByteData对象中设置字节时,是否有任何原因需要这种特定的信息顺序?如果有,我可以在哪里找到文档来显示所有的内容?另外,如果我理解正确,这不会接受来自外部源的数据,而是数据是rgb循环,对吗?搜索
bmp头格式
例如,对于格式。是的,它需要来自外部源的数据!上面的代码只生成标题(对于给定的宽度/高度值,您只需要生成一次标题)。然后,您需要附加包含位图的字节数组(必须是宽*高字节长)到标头字节数组。我更新了标头类,因此您只需调用
appendBitmap
,它就会返回一个完整有效的BMP,为
图像做好准备。memory
InstanceImageCodec
。还显示了它在示例应用程序中的用法。我正试图在自己的项目中使用该类来转换一个ByteData对象,即ui.ImageByteFormat.rawRgba格式。我的字节数据的长度是宽度*高度的四倍。因此,每个像素有四个字节。有没有办法将此数据写入BMP图像类型以显示图像?旁注:
dart:ui
函数
decodeImageFromPixels
现在使创建
dart:ui::image
更容易了。No需要在BMP标题前添加更多内容。您仍然需要显示图像(例如使用
CustomPainter
)。