Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 将图像切成等份,或者只调用图像的一部分?飞镖_Flutter_Dart - Fatal编程技术网

Flutter 将图像切成等份,或者只调用图像的一部分?飞镖

Flutter 将图像切成等份,或者只调用图像的一部分?飞镖,flutter,dart,Flutter,Dart,我需要将图片的一部分分配到一个竞争者示例中—一个益智游戏示例。使用颤振,这是一些代码,你可以这样做: 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 max

我需要将图片的一部分分配到一个竞争者示例中—一个益智游戏示例。使用颤振,这是一些代码,你可以这样做:

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;
}
import'dart:math';
进口“包装:颤振/材料.省道”;
类PuzzlePiece扩展了StatefulWidget{
最终图像;
最终尺寸图像尺寸;
最后一行;
最终整数列;
最终int maxRow;
最终int maxCol;
拼图(
{键,
@需要这个图像,
@需要此图像大小,
@需要此行,
@需要这个,
@需要此.maxRow,
@需要此参数(maxCol})
:super(key:key);
@凌驾
PuzzlePieceState createState(){
返回新的状态();
}
}
类状态扩展状态{
双层顶;
左双;
@凌驾
小部件构建(构建上下文){
最终imageWidth=MediaQuery.of(context).size.width;
final imageHeight=MediaQuery.of(context).size.height*MediaQuery.of(context).size.width/widget.imageSize.width;
最终工件宽度=imageWidth/widget.maxCol;
最终工件高度=imageHeight/widget.maxRow;
if(top==null){
top=Random().nextInt((imageHeight-pieceHeight).ceil()).toDouble();
top-=widget.row*工件高度;
}
if(left==null){
left=Random().nextInt((imageWidth-pieceWidth.ceil()).toDouble();
left-=widget.col*工件宽度;
}
返回定位(
顶:顶,,
左:左,,
宽度:图像宽度,
孩子:克利帕斯(
孩子:定制油漆(
foregroundPainter:PuzzlePiecePainter(widget.row,widget.col,widget.maxRow,widget.maxCol),
子:widget.image
),
clipper:PuzzlePieceClipper(widget.row,widget.col,widget.maxRow,widget.maxCol),
),
);
}
}
//此类用于将图像剪裁到拼图块路径
类Clipper扩展了CustomClipper{
最后一行;
最终整数列;
最终int maxRow;
最终int maxCol;
拼图剪辑器(this.row,this.col,this.maxRow,this.maxCol);
@凌驾
路径getClip(大小){
返回getPiecePath(大小、行、列、maxRow、maxCol);
}
@凌驾
bool shouldReclip(CustomClipper oldClipper)=>false;
}
//此类用于围绕剪裁图像绘制边框
类painter扩展了CustomPainter{
最后一行;
最终整数列;
最终int maxRow;
最终int maxCol;
拼图绘制(this.row,this.col,this.maxRow,this.maxCol);
@凌驾
空心油漆(帆布,尺寸){
最终油漆=油漆()
…颜色=颜色(0x80FFFFFF)
…风格=绘画风格笔划
..冲程宽度=1.0;
drawPath(getPiecePath(大小、行、列、maxRow、maxCol)、绘制);
}
@凌驾
bool应重新绘制(自定义代理){
返回false;
}
}
//这是用于剪裁图像并在其周围绘制边框的路径;在这里,我们实际绘制了拼图
路径getPiecePath(大小、整数行、整数列、整数maxRow、整数maxCol){
最终宽度=size.width/maxCol;
最终高度=size.height/maxRow;
最终偏移量x=柱*宽度;
最终偏移量=行*高度;
最终尺寸=高度/4;
var path=path();
path.moveTo(offsetX,offsetY);
如果(行==0){
//顶部侧件
path.lineTo(偏移量+宽度,偏移量);
}否则{
//顶部凸起
路径.lineTo(偏移量+宽度/3,偏移量);
path.cubicTo(offsetX+width/6,offsetY-bumpSize,offsetX+width/6*5,offsetY-bumpSize,offsetX+width/3*2,offsetY);
path.lineTo(偏移量+宽度,偏移量);
}
if(col==maxCol-1){
//右侧件
path.lineTo(偏移量+宽度,偏移量+高度);
}否则{
//右凸点
path.lineTo(偏移量+宽度,偏移量+高度/3);
path.cubicTo(offsetX+width-bumpSize,offsetY+height/6,offsetX+width-bumpSize,offsetY+height/6*5,offsetX+width,offsetY+height/3*2);
path.lineTo(偏移量+宽度,偏移量+高度);
}
如果(行==maxRow-1){
//底部侧块
path.lineTo(偏移量x,偏移量+高度);
}否则{
//底部隆起
path.lineTo(偏移量+宽度/3*2,偏移量+高度);
path.cubicTo(offsetX+width/6*5,offsetY+height-bumpSize,offsetX+width/6,offsetY+height-bumpSize,offsetX+width/3,offsetY+height);
path.lineTo(偏移量x,偏移量+高度);
}
如果(列==0){
//左侧件
path.close();
}否则{
//左凸点
路径.lineTo(偏移量x,偏移量+高度/3*2);
path.cubicTo(offsetX-bumpSize,offsetY+height/6*5,offsetX-bumpSize,offsetY+height/6,offsetX,offsetY+height/3);
path.close();
}
返回路径;
}
我找到了这段代码,但我选择的部分是你发送的,图像和制作的部分,现在重要的是要知道它是如何使用的,使它成为一个新的有状态类,接收图像和一些你需要查看的其他参数,以便可以自定义你需要什么,如行数和列数,最小y最大值和图像本身,its使用一个新类扩展CustomClipper并点击它的方式实际上是创建片段的方法,通过计算行数和列数以及接收图像的宽度和高度

现在他使用的是这样的
path.cubicTo(offsetX+width-bumpSize,offsetY+height/6,offsetX+width-bumpSize,offsetY+height/6*5,offsetX+width,offsetY+height/3*2)
但是创建拼图凹凸形状是很困难的,所以如果您不需要它,可以忽略它


您可以对这些代码稍加修改,看看它将如何满足您的需要。

看,这是一些代码,您可以如何做到这一点:

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;
}
import'dart:math';
进口“包装:颤振/材料.省道”;
类PuzzlePiece扩展了StatefulWidget{
最终图像;
最终尺寸图像尺寸;
最后一行;