102 lines
2.4 KiB
Dart
102 lines
2.4 KiB
Dart
import 'dart:ui' as ui;
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
class MaskedTicketImage extends StatefulWidget {
|
|
final String imagePath;
|
|
final String maskPath;
|
|
final double width;
|
|
final double height;
|
|
|
|
const MaskedTicketImage({
|
|
super.key,
|
|
required this.imagePath,
|
|
required this.maskPath,
|
|
required this.width,
|
|
required this.height,
|
|
});
|
|
|
|
@override
|
|
State<MaskedTicketImage> createState() => _MaskedTicketImageState();
|
|
}
|
|
|
|
class _MaskedTicketImageState extends State<MaskedTicketImage> {
|
|
ui.Image? image;
|
|
ui.Image? mask;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_loadImages();
|
|
}
|
|
|
|
Future<void> _loadImages() async {
|
|
final img = await _loadAsset(widget.imagePath);
|
|
final maskImg = await _loadAsset(widget.maskPath);
|
|
if (mounted) {
|
|
setState(() {
|
|
image = img;
|
|
mask = maskImg;
|
|
});
|
|
}
|
|
}
|
|
|
|
Future<ui.Image> _loadAsset(String asset) async {
|
|
final data = await DefaultAssetBundle.of(context).load(asset);
|
|
final codec = await ui.instantiateImageCodec(data.buffer.asUint8List());
|
|
final frame = await codec.getNextFrame();
|
|
return frame.image;
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
if (image == null || mask == null) {
|
|
return SizedBox(
|
|
width: widget.width,
|
|
height: widget.height,
|
|
child: const Center(child: CircularProgressIndicator(strokeWidth: 1.5)),
|
|
);
|
|
}
|
|
|
|
return CustomPaint(
|
|
size: Size(widget.width, widget.height),
|
|
painter: _MaskedPainter(image!, mask!),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _MaskedPainter extends CustomPainter {
|
|
final ui.Image image;
|
|
final ui.Image mask;
|
|
|
|
_MaskedPainter(this.image, this.mask);
|
|
|
|
@override
|
|
void paint(Canvas canvas, Size size) {
|
|
final paint = Paint();
|
|
|
|
// Fill background to avoid black transparency
|
|
canvas.drawColor(Colors.transparent, BlendMode.srcOver);
|
|
|
|
// Draw base image
|
|
canvas.drawImageRect(
|
|
image,
|
|
Rect.fromLTWH(0, 0, image.width.toDouble(), image.height.toDouble()),
|
|
Rect.fromLTWH(0, 0, size.width, size.height),
|
|
paint,
|
|
);
|
|
|
|
// Apply mask
|
|
paint.blendMode = BlendMode.dstIn;
|
|
canvas.drawImageRect(
|
|
mask,
|
|
Rect.fromLTWH(0, 0, mask.width.toDouble(), mask.height.toDouble()),
|
|
Rect.fromLTWH(0, 0, size.width, size.height),
|
|
paint,
|
|
);
|
|
}
|
|
|
|
@override
|
|
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
|
|
}
|