无法拍打屏幕截图 [英] Unable to take screenshot in flutter
问题描述
package:flutter/src/rendering/proxy_box.dart':失败的断言:2813行pos 12:'!debugNeedsPaint':不正确.
package:flutter/src/rendering/proxy_box.dart': Failed assertion: line 2813 pos 12: '!debugNeedsPaint': is not true.
我正试图拍张屏幕截图,但出现异常了.我访问了许多链接,但没有任何帮助.
I am trying to take screenshot in flutter, but I am getting exception. I visited many links but nothing worked.
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);
}
}
推荐答案
You can find official toImage
example here. But it looks like it doesn't work without delay between button tap and toImage
call.
官方存储库中存在一个问题: https://github.com/flutter/flutter/issues/22308
There is an issue in the official repository: https://github.com/flutter/flutter/issues/22308
发生这种情况的原因:您的点击会初始化按钮的动画,并且递归调用包括父母在内的 RenderObject.markNeedsPaint
,因此您应等待 debugNeedsPaint
为假
.在这种情况下, toImage
函数只会引发断言错误:
The cause for this: your tap initializes animation for a button and RenderObject.markNeedsPaint
gets called recursively including parents, so you should wait while debugNeedsPaint
will be false
again. toImage
function just throws assertion error in this case:
Future<ui.Image> toImage({ double pixelRatio = 1.0 }) {
assert(!debugNeedsPaint);
final OffsetLayer offsetLayer = layer;
return offsetLayer.toImage(Offset.zero & size, pixelRatio: pixelRatio);
}
bool get debugNeedsPaint {
bool result;
assert(() {
result = _needsPaint;
return true;
}());
return result;
}
实际上 assert
函数仅用于开发,因此您可以看到生产中的错误不会有麻烦.但是我不知道您会遇到什么样的麻烦,也许没有.)
Actually assert
function is used only in development, so as you can see you will not have the trouble with the error in production. But I don't know what kind of troubles you can get instead, probably no ).
下一个代码不是很好,但是可以工作:
The next code is not great but it works:
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
),
),
);
}
}
这篇关于无法拍打屏幕截图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!