gpt4 book ai didi

flutter - 使用 Custom Painter 在 Flutter 中遮盖两个图像

转载 作者:行者123 更新时间:2023-12-03 03:23:31 29 4
gpt4 key购买 nike

你好,谁能告诉我为什么这个掩蔽尝试的背景是黑色的。这一定很接近,但我就是无法杀死背景。我看到其他人提到 saveLayer(rect, paint) 是这里的关键,因为它将整个 Canvas 矩形插入掩蔽操作。 This question (无屏蔽操作)和this one (没有实际答案)是相似的,但对我没有用。

main.dart

import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);

final String title;

@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
ui.Image mask;
ui.Image image;

@override
void initState() {
super.initState();
load('images/squircle.png').then((i) {
setState(() {
mask = i;
});
});
load('images/noodlejpg.jpg').then((i) {
setState(() {
image = i;
});
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(backgroundColor: Colors.blue, title: Text('I am a title')),
body: SafeArea(
child: SizedBox(
width: 200.0,
height: 200.0,
child: CustomPaint(painter: OverlayPainter(mask, image)),
),
),
);
}

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 mask;
ui.Image image;

OverlayPainter(this.mask, this.image);

@override
void paint(Canvas canvas, Size size) {
var paint = new Paint();
paint.isAntiAlias = true;

if (image != null) {
var rect = Rect.fromLTRB(0, 0, 200, 200);
Size outputSize = rect.size;
Size inputSize = Size(image.width.toDouble(), image.height.toDouble());
final FittedSizes fittedSizes =
applyBoxFit(BoxFit.cover, inputSize, outputSize);
final Size sourceSize = fittedSizes.source;

canvas.save();
final Rect sourceRect = Alignment.center.inscribe(
sourceSize,
Offset.zero & inputSize,
);
canvas.drawImageRect(image, sourceRect, rect, paint);
canvas.restore();
}

if (mask != null) {
var rect = Rect.fromLTRB(0, 0, 200, 200);
Size outputSize = rect.size;
Size inputSize = Size(mask.width.toDouble(), mask.height.toDouble());
final FittedSizes fittedSizes =
applyBoxFit(BoxFit.cover, inputSize, outputSize);
final Size sourceSize = fittedSizes.source;

canvas.saveLayer(rect, Paint()..blendMode = BlendMode.dstIn);

final Rect sourceRect = Alignment.center.inscribe(
sourceSize,
Offset.zero & inputSize,
);
canvas.drawImageRect(mask, sourceRect, rect, paint);
canvas.restore();
}
}

@override
bool shouldRepaint(OverlayPainter oldDelegate) {
return mask != oldDelegate.mask || image != oldDelegate.image;
}
}

面条jpg.jpg

enter image description here

松鼠.jpg

enter image description here

结果

enter image description here

最佳答案

作为没有任何 CustomPainters 的选项

import 'dart:typed_data';
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(),
body: SafeArea(
child: Center(
child: SizedBox(
width: 300,
height: 300,
child: MaskedImage(asset: 'images/noodlejpg.jpeg', mask: 'images/circle.png'),
),
),
),
),
);
}
}

class MaskedImage extends StatelessWidget {
final String asset;
final String mask;

MaskedImage({@required this.asset, @required this.mask});

@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) {
return FutureBuilder<List>(
future: _createShaderAndImage(asset, mask, constraints.maxWidth, constraints.maxHeight),
builder: (context, snapshot) {
if (!snapshot.hasData) return const SizedBox.shrink();
return ShaderMask(
blendMode: BlendMode.dstATop,
shaderCallback: (rect) => snapshot.data[0],
child: snapshot.data[1],
);
},
);
});
}

Future<List> _createShaderAndImage(String asset, String mask, double w, double h) async {
ByteData data = await rootBundle.load(asset);
ByteData maskData = await rootBundle.load(mask);

Codec codec = await instantiateImageCodec(maskData.buffer.asUint8List(), targetWidth: w.toInt(), targetHeight: h.toInt());
FrameInfo fi = await codec.getNextFrame();

ImageShader shader = ImageShader(fi.image, TileMode.clamp, TileMode.clamp, Matrix4.identity().storage);
Image image = Image.memory(data.buffer.asUint8List(), fit: BoxFit.cover, width: w, height: h);
return [shader, image];
}
}

enter image description here

关于flutter - 使用 Custom Painter 在 Flutter 中遮盖两个图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60468768/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com