flutter - 将图像切成相等的部分 - 或者只是调用图像的一部分?颤振 - 飞镖
问题描述
我需要将图片的一部分分配给竞争者示例 - 益智游戏的示例。使用颤振
解决方案
看这是一些代码,你可以如何做到这一点:
import 'dart:math';
import 'package:flutter/material.dart';
class PuzzlePiece extends StatefulWidget {
final Image image;
final Size imageSize;
final int row;
final int col;
final int maxRow;
final int maxCol;
PuzzlePiece(
{Key key,
@required this.image,
@required this.imageSize,
@required this.row,
@required this.col,
@required this.maxRow,
@required this.maxCol})
: super(key: key);
@override
PuzzlePieceState createState() {
return new PuzzlePieceState();
}
}
class PuzzlePieceState extends State<PuzzlePiece> {
double top;
double left;
@override
Widget build(BuildContext context) {
final imageWidth = MediaQuery.of(context).size.width;
final imageHeight = MediaQuery.of(context).size.height * MediaQuery.of(context).size.width / widget.imageSize.width;
final pieceWidth = imageWidth / widget.maxCol;
final pieceHeight = imageHeight / widget.maxRow;
if (top == null) {
top = Random().nextInt((imageHeight - pieceHeight).ceil()).toDouble();
top -= widget.row * pieceHeight;
}
if (left == null) {
left = Random().nextInt((imageWidth - pieceWidth).ceil()).toDouble();
left -= widget.col * pieceWidth;
}
return Positioned(
top: top,
left: left,
width: imageWidth,
child: ClipPath(
child: CustomPaint(
foregroundPainter: PuzzlePiecePainter(widget.row, widget.col, widget.maxRow, widget.maxCol),
child: widget.image
),
clipper: PuzzlePieceClipper(widget.row, widget.col, widget.maxRow, widget.maxCol),
),
);
}
}
// this class is used to clip the image to the puzzle piece path
class PuzzlePieceClipper extends CustomClipper<Path> {
final int row;
final int col;
final int maxRow;
final int maxCol;
PuzzlePieceClipper(this.row, this.col, this.maxRow, this.maxCol);
@override
Path getClip(Size size) {
return getPiecePath(size, row, col, maxRow, maxCol);
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
// this class is used to draw a border around the clipped image
class PuzzlePiecePainter extends CustomPainter {
final int row;
final int col;
final int maxRow;
final int maxCol;
PuzzlePiecePainter(this.row, this.col, this.maxRow, this.maxCol);
@override
void paint(Canvas canvas, Size size) {
final Paint paint = Paint()
..color = Color(0x80FFFFFF)
..style = PaintingStyle.stroke
..strokeWidth = 1.0;
canvas.drawPath(getPiecePath(size, row, col, maxRow, maxCol), paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
// this is the path used to clip the image and, then, to draw a border around it; here we actually draw the puzzle piece
Path getPiecePath(Size size, int row, int col, int maxRow, int maxCol) {
final width = size.width / maxCol;
final height = size.height / maxRow;
final offsetX = col * width;
final offsetY = row * height;
final bumpSize = height / 4;
var path = Path();
path.moveTo(offsetX, offsetY);
if (row == 0) {
// top side piece
path.lineTo(offsetX + width, offsetY);
} else {
// top bump
path.lineTo(offsetX + width / 3, offsetY);
path.cubicTo(offsetX + width / 6, offsetY - bumpSize, offsetX + width / 6 * 5, offsetY - bumpSize, offsetX + width / 3 * 2, offsetY);
path.lineTo(offsetX + width, offsetY);
}
if (col == maxCol - 1) {
// right side piece
path.lineTo(offsetX + width, offsetY + height);
} else {
// right bump
path.lineTo(offsetX + width, offsetY + height / 3);
path.cubicTo(offsetX + width - bumpSize, offsetY + height / 6, offsetX + width - bumpSize, offsetY + height / 6 * 5, offsetX + width, offsetY + height / 3 * 2);
path.lineTo(offsetX + width, offsetY + height);
}
if (row == maxRow - 1) {
// bottom side piece
path.lineTo(offsetX, offsetY + height);
} else {
// bottom bump
path.lineTo(offsetX + width / 3 * 2, offsetY + height);
path.cubicTo(offsetX + width / 6 * 5, offsetY + height - bumpSize, offsetX + width / 6, offsetY + height - bumpSize, offsetX + width / 3, offsetY + height);
path.lineTo(offsetX, offsetY + height);
}
if (col == 0) {
// left side piece
path.close();
} else {
// left bump
path.lineTo(offsetX, offsetY + height / 3 * 2);
path.cubicTo(offsetX - bumpSize, offsetY + height / 6 * 5, offsetX - bumpSize, offsetY + height / 6, offsetX, offsetY + height / 3);
path.close();
}
return path;
}
我在这里找到了这段代码,但是我选择的那部分是您发送和图像并制作碎片的部分,现在了解它用于制作它的方式很重要,因为新的有状态类接收图像和您需要的其他一些参数看起来可以自定义您需要的内容,例如行数和列数,最小 y 最大值和图像本身,它使用扩展 CustomClipper 的新类完成它的方式,并点击它实际上创建切割计算的部分与行数和列数以及接收到的图像的宽度和高度。
现在他正在使用这个,path.cubicTo(offsetX + width - bumpSize, offsetY + height / 6, offsetX + width - bumpSize, offsetY + height / 6 * 5, offsetX + width, offsetY + height / 3 * 2);
但它是用来创建拼图凹凸形式的,所以如果你不需要这个,你可以省略它。
您可以稍微玩一下该代码,看看它如何满足您的需求。
推荐阅读
- amazon-web-services - 如何使 aws sagemaker 中的这个 IAM 角色错误消失?
- opencv - 错误:(-215:断言失败)totalSampleCount > 0 in function 'GMM::endLearning'
- mysql - MySQL 使用带有 IN 子查询的 CASE WHEN
- inno-setup - 在 Inno Setup 中使用 ISSI(添加背景图像)时实现事件函数 InitializeWizard:重复标识符“INITIALIZEWIZARD”
- git - 为什么当我只写一些代码时我的 .git 总是更大?
- sql-server - 无法使用 FreeTDS 和 ODBC (raspberry pi raspbian) 连接到 SQL Server
- python - 如何将日期列表转换为字符串列表
- powershell - cURL 到 PowerShell - --data 中的双哈希表?
- java - 如何将 Date.getTime() 转换为小时并计算差异
- javascript - 在 Dialogflow 中添加和删除购物车中的商品