📅  最后修改于: 2023-12-03 14:50:49.028000             🧑  作者: Mango
本文将介绍一个问题,即在图像抖动时,Dart 中使用的墨水池无法起作用的情况。
墨水池是一个方便的工具,可用于在需要时生成指定数量的对象,而不必在每次需要对象时都创建一个新对象。这对于一些开销很大的对象来说非常有用,比如像位图这样的图像对象。
在 Dart 中,墨水池通常与 rootBundle
类一起使用,如下所示:
final bytes = await rootBundle.load('assets/image.png');
final image = await decodeImageFromList(bytes.buffer.asUint8List());
final pool = ImagePool();
final frame = pool.borrowFrame(image.width, image.height);
frame.drawImage(image, 0, 0);
然而,当在图像抖动时,实际上会创建新的帧对象,而不是从墨水池中获取现有的帧对象。这是因为图像抖动会在每个帧之间随机移动像素,并且这种运动会使现有的帧无效。
因此,在图像抖动期间,墨水池不起作用。
为了解决这个问题,我们可以手动实现一个帧对象池,以确保帧对象的重用。
class FramePool {
final List<ImageFrame> _pool = [];
ImageFrame borrowFrame(int width, int height) {
if (_pool.isEmpty) {
return ImageFrame(width, height);
} else {
final frame = _pool.removeLast();
frame.setSize(width, height);
return frame;
}
}
void returnFrame(ImageFrame frame) {
_pool.add(frame);
}
}
然后,我们可以将 FramePool
与使用 dart:ui
库的图像抖动代码一起使用,如下所示:
final bytes = await rootBundle.load('assets/image.png');
final image = await decodeImageFromList(bytes.buffer.asUint8List());
final pool = FramePool();
for (var i = 0; i < 10; ++i) {
final frame = pool.borrowFrame(image.width, image.height);
frame.drawImage(image, -i, -i);
// Draw some other things...
pool.returnFrame(frame);
}
现在,在图像抖动期间,我们可以通过 FramePool
对象重用帧对象,并避免浪费大量内存。
在 Dart 中,图像抖动会使墨水池无法起作用,我们可以手动实现一个帧对象池以避免浪费大量内存。