Dart 颤振中字节数据的处理

Dart 颤振中字节数据的处理,dart,flutter,Dart,Flutter,我正在尝试使用此函数获取不同偏移的一系列像素颜色 _getColor(ByteData rgbaImageData, int x, int y) { var byteOffset = x * 4 + y * imageWidth * 4; var r = rgbaImageData.getUint8(byteOffset); var g = rgbaImageData.getUint8(byteOffset + 1); var b = rgbaImageData.getUint8(byte

我正在尝试使用此函数获取不同偏移的一系列像素颜色

   _getColor(ByteData rgbaImageData, int x, int y) {
var byteOffset = x * 4 + y * imageWidth * 4;
var r = rgbaImageData.getUint8(byteOffset);
var g = rgbaImageData.getUint8(byteOffset + 1);
var b = rgbaImageData.getUint8(byteOffset + 2);
var a = rgbaImageData.getUint8(byteOffset + 3);
return Color.fromARGB(a, r, g, b);
}


但是执行起来需要很长时间,有什么解决方案吗?

它不应该那么慢,但您可以减少读取次数:

Color getColor(ByteData rgbaData, int x, int y) {
  var byteOffset = (x + y * imageWidth) * 4;
  var rgba = rgbaImageData.getUint32(byteOffset);
  return Color(argb);
}
它只对每种颜色执行一次(可能未对齐)读取,并且不必重新组合字节

或者,您可以将键入数据的类型更改为
Uint8List

  var bytes = Uint8List.view(
    rgbaImageData.buffer, rgbaImageData.offsetInBytes, rgbaImageData.lengthInBytes);
...
  var color = _getColor(bytes, x, y);
...
Color _getColor(Uint8List bytes, int x, int y) {
  var byteOffset = (x + y * imageWith) * 4;
  var r = bytes[byteOffset];
  var g = bytes[byteOffset + 1]; 
  var b = bytes[byteOffset + 2];
  var a = bytes[byteOffset + 3];
  return Color.fromARGB(a, r, g, b);
}
这可能比原来的更有效,但可能不是很多

您甚至可以将原始缓冲区解释为
uint32列表
,但这仅在
offsetInBytes
是四的倍数时有效,因为
uint32列表
要求数据32位对齐(这也是为什么它可能比
ByteData
稍微高效的原因)。如果
offsetInBytes
始终为零,这可能也适用于您。 例如:

另一个可能比较慢的原因是,如果遍历整个图像,您将分配大量的
颜色
对象。如果图像没有那么多不同的颜色,可以选择重用现有的颜色对象。如果图像有很多不同的颜色,缓存它们可能会导致更多的内存流失。 例如:

Map\u colorCache={};
const int_maxCacheSize=1024;
颜色createColor(int argb){
var result=_colorCache[argb];
if(result!=null)返回结果;
结果=颜色(argb);
if(\u colorCache.length=\u maxCacheSize){
_colorCache.remove(_colorCache.keys.first);
}
_colorCache[argb]=结果;
返回结果;
}

然后使用
createColor(argb)
而不是
Color(argb)
。同样,如果您的图像有许多不同的颜色,并且没有相同颜色的大补丁,那么这很可能只是开销。

如果是UINT32列表,它将如何工作?offsetInBytes在Irn时始终为零
  var words = Uint32List.view(
    rgbaImageData.buffer, 
    rgbaImageData.offsetInBytes, 
    rgbaImageData.lengthInBytes ~/ Uint32List.bytesPerElement);
...
  var color = _getColor(words, x, y);
...
Color _getColor(Uint32List words, int x, int y) {
  var offset = x + y * imageWith;
  return Color(words[offset]);
}
Map<int, Color> _colorCache = {};
const int _maxCacheSize = 1024;
Color createColor(int argb) {
  var result = _colorCache[argb];
  if (result != null) return result;
  result = Color(argb);
  if (_colorCache.length == _maxCacheSize) {
    _colorCache.remove(_colorCache.keys.first);
  }
  _colorCache[argb] = result;
  return result;
}