【发布时间】:2021-10-22 18:01:07
【问题描述】:
我正在尝试开发一个适用于 Flutter 中的像素转换的应用程序。在我目前的方法中,我通过 FFI 使用 Rust 来执行所有像素操作算法,但我注意到它的性能不是很好。在我的示例中,我使用滑块将 RED 通道从 0 更改为 255。我怀疑我没有使用最佳方法来渲染图像。我想要可以帮助提高性能的建议。这是一个例子:
我的组件
class _RedChannelPageState extends State<RedChannelPage> {
Uint8List? _imageAsBytes;
double _sliderValue = 0;
ui.Image? _img;
void _pickImage() async {
final image = await ImagePicker().pickImage(source: ImageSource.gallery);
if (image != null) {
final imageAsbytes = await image.readAsBytes();
loadImage(imageAsBytes).then((value) => {
setState(() {
_img = value;
_imageAsBytes = imageAsbytes;
})
});
}
}
Future<ui.Image> loadImage(Uint8List imageAsBytes) async {
final Completer<ui.Image> completer = Completer();
ui.decodeImageFromList(imageAsBytes, (ui.Image img) {
return completer.complete(img);
});
return completer.future;
}
void _onSlideChange(double value) async {
setState(() {
_sliderValue = value;
});
final imgResult =
await compute(spawnThread, [_imageAsBytes!, value.round()]);
final decodedImage = await loadImage(imgResult);
setState(() {
_img = decodedImage;
});
}
static Uint8List spawnThread(List<dynamic> list) {
final result = FFI(imageAsBytes: list[0]).changeRed(list[1]);
return result;
}
我的 FFI 课程
final Pointer<Uint8> Function(Pointer<Uint8> data, int len, int red)
nativeRedChannel = nativeAddLib
.lookup<
NativeFunction<
Pointer<Uint8> Function(
Pointer<Uint8>, Int32, Int32)>>("red_channel")
.asFunction();
class FFI {
const FFI({
required this.imageAsBytes,
});
final Uint8List imageAsBytes;
// send a pointer of Uint8List to rust function and return a encoded JPEG with alterations
Uint8List changeRed(int redValue) {
final Pointer<Uint8> allocation =
malloc.allocate<Uint8>(imageAsBytes.length * sizeOf<Uint8>());
allocation.asTypedList(imageAsBytes.length).setAll(0, imageAsBytes);
final pointerResult =
nativeRedChannel(allocation, imageAsBytes.length, redValue);
final result = pointerResult.asTypedList(imageAsBytes.length);
return result;
}
}
【问题讨论】: