Flutter截图在部分设备(Tecno BE8)中出现垂直镜像翻转问题
解决方案
针对部分设备(如Tecno BE8)使用RenderRepaintBoundary截图出现垂直镜像翻转的问题,可通过以下两种方案修复:
方案一:展示时临时翻转图像
如果仅需在APP内展示截图,无需修改原始数据,直接在展示时用Transform.flip垂直翻转图像即可:
import 'package:device_info_plus/device_info_plus.dart'; import 'dart:io'; void _showCapturedImage(BuildContext context, Uint8List image) async { bool needFlip = await _checkNeedFlip(); showDialog( context: context, builder: (context) { return AlertDialog( content: needFlip ? Transform.flip(flipY: true, child: Image.memory(image)) : Image.memory(image), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('Close'), ), ], ); }, ); } // 检测是否为需要翻转的设备(可扩展型号列表) Future<bool> _checkNeedFlip() async { final deviceInfo = DeviceInfoPlugin(); if (Platform.isAndroid) { final androidInfo = await deviceInfo.androidInfo; return ['Tecno BE8'].contains(androidInfo.model); } return false; }
方案二:截图后永久修正图像数据
如果需要保存或分享修正后的截图,可在获取截图后通过Canvas绘制翻转后的图像,再转换为Uint8List:
import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:flutter/material.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'dart:io'; final GlobalKey _globalKey = GlobalKey(); Future<Uint8List?> _captureWidget() async { try { RenderRepaintBoundary boundary = _globalKey.currentContext!.findRenderObject() as RenderRepaintBoundary; ui.Image image = await boundary.toImage(pixelRatio: 3.0); bool needFlip = await _checkNeedFlip(); if (!needFlip) { ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png); Uint8List uint8List = byteData!.buffer.asUint8List(); image.dispose(); return uint8List; } // 绘制垂直翻转后的图像 final recorder = ui.PictureRecorder(); final canvas = Canvas(recorder); // 平移画布到图像底部,再沿Y轴翻转坐标系 canvas.translate(0, image.height.toDouble()); canvas.scale(1, -1); canvas.drawImage(image, Offset.zero, Paint()); final picture = recorder.endRecording(); final flippedImage = await picture.toImage(image.width, image.height); ByteData? byteData = await flippedImage.toByteData(format: ui.ImageByteFormat.png); Uint8List uint8List = byteData!.buffer.asUint8List(); // 释放资源避免内存泄漏 image.dispose(); flippedImage.dispose(); picture.dispose(); return uint8List; } catch (e) { print('Error capturing widget: $e'); return null; } } // 设备检测逻辑同方案一 Future<bool> _checkNeedFlip() async { final deviceInfo = DeviceInfoPlugin(); if (Platform.isAndroid) { final androidInfo = await deviceInfo.androidInfo; return ['Tecno BE8'].contains(androidInfo.model); } return false; }
关键说明
- 该问题根源是部分设备的GPU渲染管线实现与Flutter图像坐标系不兼容,导致
toImage输出的图像垂直翻转。 - 设备检测逻辑可根据实际出现问题的型号扩展,避免影响正常设备的截图展示。
内容的提问来源于stack exchange,提问作者Mobarak Ali
相关产品推荐
相关产品推荐

