Created with <3 with dartpad.dev.
Created
October 17, 2022 16:21
-
-
Save Gavin0x0/c7fb37092bfc78d5f11a4abab4a0906e to your computer and use it in GitHub Desktop.
zealous-lantern-8672
This file contains 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:convert'; | |
import 'dart:math'; | |
import 'dart:typed_data'; | |
import 'dart:ui' as ui; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter/rendering.dart'; | |
void main() => runApp(const MyApp()); | |
class UiImagePainter extends CustomPainter { | |
final ui.Image image; | |
UiImagePainter(this.image); | |
@override | |
void paint(ui.Canvas canvas, ui.Size size) { | |
var hr = size.height / image.height; | |
var wr = size.width / image.width; | |
double ratio; | |
double translateX; | |
double translateY; | |
if (hr < wr) { | |
ratio = hr; | |
translateX = (size.width - (ratio * image.width)) / 2; | |
translateY = 0.0; | |
} else { | |
ratio = wr; | |
translateX = 0.0; | |
translateY = (size.height - (ratio * image.height)) / 2; | |
} | |
canvas.translate(translateX, translateY); | |
canvas.scale(ratio, ratio); | |
canvas.drawImage(image, const Offset(0.0, 0.0), Paint()); | |
} | |
@override | |
bool shouldRepaint(UiImagePainter oldDelegate) { | |
return oldDelegate.image != image; | |
} | |
} | |
class UiImageDrawer extends StatelessWidget { | |
final ui.Image image; | |
const UiImageDrawer({Key? key, required this.image}) : super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
return SizedBox( | |
width: 300, | |
height: 300, | |
child: CustomPaint( | |
size: Size.infinite, | |
painter: UiImagePainter(image), | |
), | |
); | |
} | |
} | |
class MyApp extends StatefulWidget { | |
const MyApp({Key? key}) : super(key: key); | |
@override | |
MyAppState createState() => MyAppState(); | |
} | |
class MyAppState extends State<MyApp> { | |
GlobalKey<OverRepaintBoundaryState> globalKey = GlobalKey(); | |
ui.Image? image; | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
home: Scaffold( | |
appBar: AppBar(), | |
body: Row(children: [ | |
Capturer(overRepaintKey: globalKey), | |
if (image != null) UiImageDrawer(image: image!) | |
]), | |
floatingActionButton: image == null | |
? FloatingActionButton( | |
child: const Icon(Icons.camera), | |
onPressed: () async { | |
final RenderRepaintBoundary? boundary = | |
globalKey.currentContext?.findRenderObject() | |
as RenderRepaintBoundary?; | |
if (boundary != null) { | |
ui.Image captureImage = await boundary.toImage(); | |
ByteData? byteData = await captureImage.toByteData( | |
format: ui.ImageByteFormat.png); | |
final pngBytes = byteData!.buffer.asUint8List(); | |
final pngBase64 = base64Encode(pngBytes); | |
debugPrint("data:image/png;base64,$pngBase64"); | |
setState(() => image = captureImage); | |
} | |
}, | |
) | |
: FloatingActionButton( | |
onPressed: () => setState(() => image = null), | |
child: const Icon(Icons.remove), | |
), | |
), | |
); | |
} | |
} | |
class Capturer extends StatelessWidget { | |
static final Random random = Random(); | |
final GlobalKey<OverRepaintBoundaryState> overRepaintKey; | |
const Capturer({Key? key, required this.overRepaintKey}) : super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
return SingleChildScrollView( | |
child: OverRepaintBoundary( | |
key: overRepaintKey, | |
child: RepaintBoundary( | |
child: Card( | |
shape: RoundedRectangleBorder( | |
borderRadius: BorderRadius.circular(25), | |
), | |
child: Container( | |
margin: const EdgeInsets.all(20), | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
Text( | |
"This is a RenderRepaintBoundary test", | |
style: Theme.of(context) | |
.textTheme | |
.headline6 | |
?.copyWith(color: Colors.blue), | |
), | |
ClipRRect( | |
borderRadius: BorderRadius.circular(25), | |
child: Container( | |
width: 200, | |
height: 200, | |
color: Colors.grey[100], | |
child: Image.network( | |
"https://upload.wikimedia.org/wikipedia/commons/7/70/Example.png", | |
fit: BoxFit.cover, | |
), | |
), | |
), | |
], | |
), | |
), | |
), | |
), | |
), | |
); | |
} | |
} | |
class OverRepaintBoundary extends StatefulWidget { | |
final Widget child; | |
const OverRepaintBoundary({Key? key, required this.child}) : super(key: key); | |
@override | |
OverRepaintBoundaryState createState() => OverRepaintBoundaryState(); | |
} | |
class OverRepaintBoundaryState extends State<OverRepaintBoundary> { | |
@override | |
Widget build(BuildContext context) { | |
return widget.child; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment