Flutter Web如何捕获全屏并直接保存至相册
Flutter Web 实现全屏截图并保存至相册的方案
核心限制说明
Web 端没有直接写入系统相册的原生 API,必须通过浏览器提供的交互类 API 实现,核心流程是:捕获全屏截图 → 通过浏览器能力引导用户保存到相册。
一、使用浏览器原生 API 实现(无第三方包依赖)
1. 捕获全屏截图
Flutter Web 的页面渲染在专属的 Canvas 元素中,可直接获取该 Canvas 并转为图片数据:
import 'dart:html' as html; import 'dart:typed_data'; Future<Uint8List?> captureFullScreen() async { // 获取 Flutter Web 渲染用的 Canvas final flutterCanvas = html.document.querySelector('canvas.flutter-web-renderer') as html.CanvasElement?; if (flutterCanvas == null) return null; // 创建新 Canvas 复制原内容(确保完整捕获) final canvas = html.CanvasElement( width: flutterCanvas.width, height: flutterCanvas.height, ); final context = canvas.context2D; context.drawImageElement(flutterCanvas, 0, 0); // 将 Canvas 转为 PNG 字节数据 final blob = await canvas.toBlob('image/png'); return await html.Blob([blob]).getBytes(); }
2. 引导保存至相册
提供两种兼容方案,优先使用分享 API,失败则降级为剪贴板或下载:
方案A:使用 Navigator.share() 让用户选择保存
该 API 支持直接分享图片到相册(需 HTTPS 环境,兼容 Chrome、Edge、Safari 等现代浏览器):
Future<void> saveImageToGallery(Uint8List imageBytes) async { final blob = html.Blob([imageBytes], 'image/png'); final file = html.File([blob], 'fullscreen_screenshot.png', {'type': 'image/png'}); final url = html.Url.createObjectUrlFromBlob(blob); try { // 调用浏览器分享接口,用户可选择保存到相册 await html.window.navigator.share({ 'title': '全屏截图', 'files': [file], }); } catch (e) { // 分享失败时,降级为剪贴板复制 await copyImageToClipboard(imageBytes); // 也可触发下载作为备选: // final anchor = html.AnchorElement(href: url)..setAttribute('download', 'screenshot.png')..click(); } finally { html.Url.revokeObjectUrl(url); } }
方案B:复制到剪贴板,引导用户手动粘贴到相册
兼容性更好,适合不支持分享 API 的浏览器:
Future<void> copyImageToClipboard(Uint8List imageBytes) async { final blob = html.Blob([imageBytes], 'image/png'); final clipboardItem = html.ClipboardItem({'image/png': blob}); await html.navigator.clipboard.write([clipboardItem]); // 提示用户:"截图已复制到剪贴板,请打开相册粘贴保存" }
二、第三方包简化流程
如果不想手写原生 API,可使用封装好的 Web 端截图/保存包,比如 web_image_saver(核心仍是封装上述浏览器 API),用法示例:
import 'package:web_image_saver/web_image_saver.dart'; // 捕获并保存 Future<void> captureAndSave() async { final imageBytes = await captureFullScreen(); if (imageBytes != null) { await WebImageSaver.saveImage(imageBytes, name: 'fullscreen_screenshot.png'); // 内部会自动调用分享或剪贴板逻辑 } }
关键注意事项
- 必须在 HTTPS 环境 下运行,浏览器的分享、剪贴板 API 仅支持安全上下文;
- 旧版浏览器可能不支持部分 API,需做好降级处理(比如 fallback 到文件下载);
- 若页面存在滚动内容,上述代码通过获取 Flutter 渲染 Canvas 已实现完整页面的捕获。
内容的提问来源于stack exchange,提问作者Juda
相关产品推荐
相关产品推荐

