Clipping images using png in flutter?

后端 未结 1 418
萌比男神i
萌比男神i 2021-01-06 06:15

I am trying to achieve effect demonstrated in the image at the bottom of this question, essentially I have orc graphic (square) and a png for dark cloud/smoke that I want to

1条回答
  •  粉色の甜心
    2021-01-06 07:06

    You can certainly do it with CustomPainter. Note that there are two different classes in Flutter called Image. The normal one is a Widget; the other one (part of the ui package) is closer to a bitmap. We'll be using the latter. I put two images in my assets folder (cute kitten and background with transparent hole). This shows how to load the graphics from assets, convert them to bitmaps, and how to draw those to a Canvas. End result is kitten showing through hole.

    import 'dart:ui' as ui;
    import 'dart:typed_data';
    import 'dart:async';
    
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart' show rootBundle;
    
    class ImageOverlay extends StatefulWidget {
      @override
      State createState() => new ImageOverlayState();
    }
    
    class ImageOverlayState extends State {
      ui.Image kitten;
      ui.Image hole;
    
      @override
      Widget build(BuildContext context) {
        return new SizedBox(
          width: 500.0,
          height: 500.0,
          child: new CustomPaint(
            painter: new OverlayPainter(hole, kitten),
          ),
        );
      }
    
      @override
      void initState() {
        super.initState();
        load('assets/hole.png').then((i) {
          setState(() {
            hole = i;
          });
        });
        load('assets/kitty.jpg').then((i) {
          setState(() {
            kitten = i;
          });
        });
      }
    
      Future load(String asset) async {
        ByteData data = await rootBundle.load(asset);
        ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List());
        ui.FrameInfo fi = await codec.getNextFrame();
        return fi.image;
      }
    }
    
    class OverlayPainter extends CustomPainter {
      ui.Image hole;
      ui.Image kitten;
    
      OverlayPainter(this.hole, this.kitten);
    
      @override
      void paint(Canvas canvas, Size size) {
        if (kitten != null) {
          canvas.drawImage(kitten, Offset(0.0, 0.0), new Paint());
        }
        if (hole != null) {
          canvas.drawImage(hole, Offset(0.0, 0.0), new Paint());
        }
      }
    
      @override
      bool shouldRepaint(OverlayPainter oldDelegate) {
        return hole != oldDelegate.hole || kitten != oldDelegate.kitten;
      }
    }
    

    When drawing the images to the Canvas you may need to deal with Transforms to scale the images correctly.

    I didn't get a chance to try, but have you tried a Stack with two (widget) Images positioned on top of each other?

    0 讨论(0)
提交回复
热议问题