如何在Custom Painter绘制的多边形内显示适配尺寸的图片
在CustomPainter的多边形内部绘制适配图片的解决方案
核心思路是利用Canvas的clipPath方法,先将画布裁剪为目标多边形的形状,再在裁剪区域内绘制图片,这样图片就只会显示在多边形内部。同时需要计算多边形的边界矩形,以此缩放图片来适配尺寸。
修改后的CustomPainter实现
import 'dart:ui' as ui; import 'package:flutter/material.dart'; class MyPainter extends CustomPainter { final Offset firstPoint; final Offset secondPoint; final Offset thirdPoint; final Offset fourthPoint; final ui.Image image; MyPainter( this.firstPoint, this.secondPoint, this.thirdPoint, this.fourthPoint, this.image, ); @override void paint(Canvas canvas, Size size) { // 创建目标多边形路径 final polygonPath = Path() ..addPolygon([ firstPoint, secondPoint, thirdPoint, fourthPoint, ], true); // 获取多边形的边界矩形,用于计算图片缩放和位置 final pathBounds = polygonPath.getBounds(); // 将画布裁剪为多边形形状,后续绘制仅在该区域生效 canvas.clipPath(polygonPath); // 计算图片缩放比例:根据需求选择填充或适配模式 final scaleX = pathBounds.width / image.width; final scaleY = pathBounds.height / image.height; // 取较大值:图片填充整个多边形(可能裁剪边缘);取较小值:图片完整显示(可能留空白) final scale = scaleX > scaleY ? scaleX : scaleY; final scaledWidth = image.width * scale; final scaledHeight = image.height * scale; // 计算图片偏移,让图片在多边形内居中 final offsetX = pathBounds.left + (pathBounds.width - scaledWidth) / 2; final offsetY = pathBounds.top + (pathBounds.height - scaledHeight) / 2; // 绘制适配后的图片 canvas.drawImageRect( image, Rect.fromLTWH(0, 0, image.width.toDouble(), image.height.toDouble()), Rect.fromLTWH(offsetX, offsetY, scaledWidth, scaledHeight), Paint(), ); } @override bool shouldRepaint(CustomPainter oldDelegate) { if (oldDelegate is MyPainter) { return firstPoint != oldDelegate.firstPoint || secondPoint != oldDelegate.secondPoint || thirdPoint != oldDelegate.thirdPoint || fourthPoint != oldDelegate.fourthPoint || image != oldDelegate.image; } return true; } }
补充:加载UI.Image的方法
要将资源图片转换为ui.Image,可以用以下异步方法:
import 'package:flutter/services.dart'; Future<ui.Image> loadAssetImage(String assetPath) async { final ByteData data = await rootBundle.load(assetPath); final ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List()); final ui.FrameInfo frameInfo = await codec.getNextFrame(); return frameInfo.image; }
内容的提问来源于stack exchange,提问作者Yonkee
相关产品推荐
相关产品推荐

