Flutter 如何在 Android 和 Linux 上正确保存 QR PNG?
数据阿明
结论
保存 PNG 时,直接使用 ui.Image.toByteData(format: ui.ImageByteFormat.png) 返回的字节。不要先把 PNG 字节转换成字符串,再用 utf8.encode 编码。这样会改变文件内容,可能导致图片无法正常打开。
这里的 pngBytes 是 PNG 二进制数据。原代码先将其转换成字符串,再把编码后的内容作为文件字节传入:
bytes: utf8.encode(String.fromCharCodes(uInt8List!)),
这种转换会改变原始二进制内容。
保存 PNG 字节
RenderRepaintBoundary 转换得到的 Uint8List 可以直接写入文件。提问者给出的方案分别处理 Android 和 Linux:在 Android 上,将字节传给 FilePicker.platform.saveFile;在 Linux 上,先获取保存路径,再用 File.writeAsBytes 写入文件。
Future<void> saveQrAsPng(Uint8List uInt8List) async {
if (Platform.isAndroid) {
await FilePicker.platform.saveFile(
dialogTitle: 'Save File:',
fileName: 'Store.png',
bytes: uInt8List,
);
} else if (Platform.isLinux) {
final outputFilePath = await FilePicker.platform.saveFile(
dialogTitle: 'Save File:',
fileName: 'Store.png',
);
if (outputFilePath != null) {
final file = await File(outputFilePath).create();
await file.writeAsBytes(uInt8List, flush: true);
}
}
}
捕获图片时,先检查 byteData 是否为空,再传递字节:
final byteData = await image.toByteData(
format: ui.ImageByteFormat.png,
);
if (byteData == null) {
return;
}
final pngBytes = byteData.buffer.asUint8List();
await vm.saveQrAsPng(pngBytes);
注意事项
saveFile 返回的路径可能为空,表示没有可用的输出路径,或者用户取消了操作。写入文件前应先检查返回值。提问者报告的测试环境是 Linux Mint 和 Android 14;其他平台或系统版本需要在实际环境中验证。
备注:内容仅供参考。
