Last active
April 25, 2024 13:17
-
-
Save PlugFox/b2445fc249f566ad6499f520e2f6808c to your computer and use it in GitHub Desktop.
Flutter get screenshot from canvas layer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:async'; | |
import 'dart:io'; | |
import 'dart:typed_data'; | |
import 'package:flutter/material.dart'; | |
import 'package:gallery_saver/gallery_saver.dart'; | |
import 'package:path/path.dart'; | |
import 'package:path_provider/path_provider.dart'; | |
import 'screenshot.dart'; | |
void main() => runApp(const App()); | |
class App extends StatelessWidget { | |
const App({super.key}); | |
Future<void> saveScreenshot(ByteData data) async { | |
File? file; | |
try { | |
final dir = await getTemporaryDirectory(); | |
file = File(join(dir.path, 'screenshot_${DateTime.now().millisecondsSinceEpoch.toRadixString(36)}.png')); | |
await file.writeAsBytes(data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes)); | |
await GallerySaver.saveImage(file.path); | |
} finally { | |
await file?.delete(); | |
} | |
} | |
@override | |
Widget build(BuildContext context) => ScreenshotScope( | |
child: MaterialApp( | |
title: 'Material App', | |
home: Scaffold( | |
appBar: AppBar( | |
title: const Text('App Bar'), | |
), | |
body: SafeArea( | |
child: Center( | |
child: SingleChildScrollView( | |
child: ScreenshotScope( | |
child: Builder( | |
builder: (context) => ElevatedButton( | |
onPressed: () => ScreenshotScope.takeScreenshot(context).then<void>(saveScreenshot), | |
child: Text('Hello World\n' * 100), | |
), | |
), | |
), | |
), | |
), | |
), | |
), | |
), | |
); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// How to take a screenshot of widgets | |
import 'dart:typed_data' as td; | |
import 'dart:ui' as ui; | |
import 'package:flutter/rendering.dart'; | |
import 'package:flutter/widgets.dart'; | |
class ScreenshotScope extends StatelessWidget { | |
const ScreenshotScope({required this.child, super.key}); | |
final Widget child; | |
static Future<td.ByteData> takeScreenshot( | |
BuildContext context, { | |
double pixelRatio = 1.0, | |
}) async { | |
RenderRepaintBoundary? boundary; | |
context.visitAncestorElements((element) { | |
if (element.widget is ScreenshotScope) return false; | |
final renderObject = element.renderObject; | |
if (renderObject is RenderRepaintBoundary) boundary = renderObject; | |
return true; | |
}); | |
if (boundary == null) throw UnsupportedError('No ScreenshotScope found'); | |
final image = await boundary!.toImage(pixelRatio: pixelRatio); | |
final bytes = await image.toByteData(format: ui.ImageByteFormat.png); | |
if (bytes is! td.ByteData) throw UnsupportedError('Error converting image to bytes'); | |
return bytes; | |
} | |
@override | |
Widget build(BuildContext context) => RepaintBoundary(child: child); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Просто обернуть виджет в ScreenshotScope.
Получение скриншота из контекста:
Ну и сохранить на диск png, например: