You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何在保存文件前缩小原始RGBA格式的屏幕截图数据?

解决Flutter录屏中高DPR图像缩容为原始尺寸的RGBA数据方案

要在保留原始RGBA格式的前提下,将高DPR捕获的屏幕图像缩回到原始逻辑尺寸以减小数据大小,可通过Flutter的Canvas直接操作图像绘制实现,全程无需编码为PNG,性能损耗极低。

实现步骤

  • 捕获高DPR图像后,获取Widget的原始逻辑尺寸(即boundary.size)
  • 使用PictureRecorder和Canvas将高DPR图像缩放到目标尺寸绘制
  • 从Recorder生成缩放后的图像,提取RGBA字节数据
  • 及时释放图像资源避免内存泄漏

完整代码示例

import 'dart:ui' as ui;
import 'package:flutter/rendering.dart';

// 屏幕捕获并缩放为原始尺寸RGBA数据的函数
Future<Uint8List> captureScaledRgba(GlobalKey key) async {
  double dpr = ui.window.devicePixelRatio;
  final boundary = key.currentContext!.findRenderObject() as RenderRepaintBoundary;

  // 捕获高DPR图像保证质量
  ui.Image highDprImage = boundary.toImageSync(pixelRatio: dpr);

  // 目标尺寸:Widget的原始逻辑尺寸
  Size targetSize = boundary.size;
  int targetWidth = targetSize.width.toInt();
  int targetHeight = targetSize.height.toInt();

  // 创建录制器与画布,准备绘制缩放后的图像
  final recorder = ui.PictureRecorder();
  final canvas = Canvas(
    recorder,
    Rect.fromLTWH(0, 0, targetWidth.toDouble(), targetHeight.toDouble()),
  );

  // 按比例缩放绘制高DPR图像,得到原始尺寸的图像
  canvas.scale(1 / dpr);
  canvas.drawImage(highDprImage, Offset.zero, Paint());

  // 生成缩放后的图像
  ui.Image scaledImage = recorder.endRecording().toImageSync(targetWidth, targetHeight);

  // 提取原始RGBA格式的字节数据
  final rawBytes = await scaledImage.toByteData(format: ui.ImageByteFormat.rawRgba);
  final uData = rawBytes!.buffer.asUint8List();

  // 释放图像资源,录屏场景必须做,防止内存泄漏
  highDprImage.dispose();
  scaledImage.dispose();

  return uData;
}

关键说明

  • 缩放逻辑:高DPR图像的像素数是原始逻辑尺寸×DPR,通过canvas.scale(1/dpr)直接将图像缩放到原始尺寸,全程是底层图像绘制操作,性能远优于编码解码
  • 资源释放:录屏时会频繁生成图像对象,必须调用dispose()释放内存,否则会快速引发内存溢出
  • 数据格式:最终输出的依然是原始RGBA字节流,完全符合你的性能与格式要求

内容的提问来源于stack exchange,提问作者jdevp2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 19:56:50