package:flutter/src/rendering/proxy_box.dart': Failed assertion: line 2813 pos 12: '!debugNeedsPaint': is not true.
我正在尝试在 flutter 中截取屏幕截图,但出现异常。我访问了许多链接,但没有任何效果。
Future<Uint8List> _capturePng() async {
try {
print('inside');
RenderRepaintBoundary boundary = _globalKey.currentContext.findRenderObject();
ui.Image image = await boundary.toImage(pixelRatio: 3.0);
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
var pngBytes = byteData.buffer.asUint8List();
var bs64 = base64Encode(pngBytes);
print(pngBytes);
print(bs64);
setState(() {});
return pngBytes;
} catch (e) {
print(e);
}
}
最佳答案
您可以找到官方toImage
示例 here .但看起来它在按钮点击和 toImage
之间没有延迟。称呼。
官方仓库有问题:https://github.com/flutter/flutter/issues/22308
造成这种情况的原因:您的点击初始化按钮和 RenderObject.markNeedsPaint
的动画被递归调用,包括 parent ,所以你应该等待 debugNeedsPaint
将是 false
再次。 toImage
在这种情况下,函数只会抛出断言错误:
Future<ui.Image> toImage({ double pixelRatio = 1.0 }) {
assert(!debugNeedsPaint);
final OffsetLayer offsetLayer = layer;
return offsetLayer.toImage(Offset.zero & size, pixelRatio: pixelRatio);
}
https://github.com/flutter/flutter/blob/f0553ba58e6455aa63fafcdca16100b81ff5c3ce/packages/flutter/lib/src/rendering/proxy_box.dart#L2857
bool get debugNeedsPaint {
bool result;
assert(() {
result = _needsPaint;
return true;
}());
return result;
}
https://github.com/flutter/flutter/blob/0ca5e71f281cd549f1b5284e339523ad93544c60/packages/flutter/lib/src/rendering/object.dart#L2011
其实
assert
函数只在开发中使用,所以你可以看到你不会在生产中遇到错误的麻烦。但我不知道你会遇到什么样的麻烦,可能没有)。下一个代码不是很好,但它有效:
class _MyHomePageState extends State<MyHomePage> {
GlobalKey globalKey = GlobalKey();
Future<Uint8List> _capturePng() async {
RenderRepaintBoundary boundary = globalKey.currentContext.findRenderObject();
if (boundary.debugNeedsPaint) {
print("Waiting for boundary to be painted.");
await Future.delayed(const Duration(milliseconds: 20));
return _capturePng();
}
var image = await boundary.toImage();
var byteData = await image.toByteData(format: ImageByteFormat.png);
return byteData.buffer.asUint8List();
}
void _printPngBytes() async {
var pngBytes = await _capturePng();
var bs64 = base64Encode(pngBytes);
print(pngBytes);
print(bs64);
}
@override
Widget build(BuildContext context) {
return RepaintBoundary(
key: globalKey,
child: Center(
child: FlatButton(
color: Color.fromARGB(255, 255, 255, 255),
child: Text('Capture Png', textDirection: TextDirection.ltr),
onPressed: _printPngBytes
),
),
);
}
}
关于flutter - 无法在 flutter 中截取屏幕截图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57645037/