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<ImageOverlay> {
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<ui.Image> 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) Image
s positioned on top of each other?