Skip to content

Instantly share code, notes, and snippets.

@Gavin0x0
Created October 17, 2022 16:21
Show Gist options
  • Select an option

  • Save Gavin0x0/c7fb37092bfc78d5f11a4abab4a0906e to your computer and use it in GitHub Desktop.

Select an option

Save Gavin0x0/c7fb37092bfc78d5f11a4abab4a0906e to your computer and use it in GitHub Desktop.

Revisions

  1. Gavin0x0 created this gist Oct 17, 2022.
    174 changes: 174 additions & 0 deletions main.dart
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,174 @@
    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;
    }
    }
    3 changes: 3 additions & 0 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    # zealous-lantern-8672

    Created with <3 with [dartpad.dev](https://dartpad.dev).