Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.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
如何在Java中分别变换形状的每一面?_Java_Image - Fatal编程技术网

如何在Java中分别变换形状的每一面?

如何在Java中分别变换形状的每一面?,java,image,Java,Image,我有一个完美的矩形图像。我想剪切图像,使其变成这样: 我该怎么做 注意:我不希望使用外部库,但如果这是唯一的方法,外部库也可以 更新:我正在研究一种算法来实现这一点,请在这里帮助我: 我已经创建了一个完整的算法。相当长。下面包含quadraside.java文件。最后一种方法,paint(Graphics,BuffereImage)修改图像并将其以自己的形状绘制到图形上: import java.awt.Color; import java.awt.Graphics; import java.

我有一个完美的矩形图像。我想剪切图像,使其变成这样:

我该怎么做

注意:我不希望使用外部库,但如果这是唯一的方法,外部库也可以

更新:我正在研究一种算法来实现这一点,请在这里帮助我:


我已经创建了一个完整的算法。相当长。下面包含
quadraside.java
文件。最后一种方法,
paint(Graphics,BuffereImage)
修改图像并将其以自己的形状绘制到图形上:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

public final class Quadrilateral extends Polygon {
    private static final long serialVersionUID = 794866732073166739L;
    public final Point p1, p2, p3, p4;
    public final Line l12, l23, l34, l41;

    public Quadrilateral(Point p1, Point p2, Point p3, Point p4) {
        super(new int[] { p1.x, p2.x, p3.x, p4.x }, new int[] { p1.y, p2.y,
                p3.y, p4.y }, 4);
        this.p1 = p1;
        this.p2 = p2;
        this.p3 = p3;
        this.p4 = p4;
        this.l12 = Quadrilateral.getLine(p1, p2);
        this.l23 = Quadrilateral.getLine(p2, p3);
        this.l34 = Quadrilateral.getLine(p3, p4);
        this.l41 = Quadrilateral.getLine(p4, p1);
    }

    public static Quadrilateral formatted(Quadrilateral quadrilateral, int w,
            int h) {
        return new Quadrilateral(Format.format(quadrilateral.p1, w, h),
                Format.format(quadrilateral.p2, w, h), Format.format(
                        quadrilateral.p3, w, h), Format.format(
                        quadrilateral.p4, w, h));
    }

    public Quadrilateral[][] grid(int x, int y) {
        Point[][] points = new Point[x + 1][y + 1];
        for (int ix = 0; ix <= x; ix++) {
            for (int iy = 0; iy <= y; iy++) {
                points[ix][iy] = this.getPointAt(x, y, ix, iy);
            }
        }
        Quadrilateral[][] qs = new Quadrilateral[x][y];
        for (int ix = 0; ix < x; ix++) {
            for (int iy = 0; iy < y; iy++) {
                qs[ix][iy] = new Quadrilateral(points[ix][iy],
                        points[ix + 1][iy], points[ix + 1][iy + 1],
                        points[ix][iy + 1]);
            }
        }
        return qs;
    }

    public ArrayList<ArrayList<Quadrilateral>> gridList(int x, int y) {
        Point[][] points = new Point[x + 1][y + 1];
        for (int ix = 0; ix <= x; ix++) {
            for (int iy = 0; iy <= y; iy++) {
                points[ix][iy] = this.getPointAt(x, y, ix, iy);
            }
        }
        ArrayList<ArrayList<Quadrilateral>> qs = new ArrayList<>(0);
        for (int ix = 0; ix < x; ix++) {
            qs.add(new ArrayList<>(y));
            for (int iy = 0; iy < y; iy++) {
                qs.get(ix).add(
                        new Quadrilateral(points[ix][iy], points[ix + 1][iy],
                                points[ix + 1][iy + 1], points[ix][iy + 1]));
            }
        }
        return qs;
    }

    public Point getPointAt(int xdiv, int ydiv, int xiter, int yiter) {
        Point n1 = this.getTopPointAt(xdiv, xiter);
        Point n2 = this.getRightPointAt(ydiv, yiter);
        Point n3 = this.getBottomPointAt(xdiv, xiter);
        Point n4 = this.getLeftPointAt(ydiv, yiter);
        Line h = Quadrilateral.getLine(n4, n2);
        Line v = Quadrilateral.getLine(n1, n3);
        return h.intersect(v, n2.x, n1.x);
    }

    public Point getTopPointAt(int div, int iter) {
        Point start = this.p1;
        Point end = this.p2;
        int xdiff = end.x - start.x;
        int ydiff = end.y - start.y;
        int xadd = (int) ((double) xdiff / (double) div) * iter;
        int yadd = (int) ((double) ydiff / (double) div) * iter;
        int x = start.x + xadd;
        int y = start.y + yadd;
        return new Point(x, y);
    }

    public Point getBottomPointAt(int div, int iter) {
        Point start = this.p4;
        Point end = this.p3;
        int xdiff = end.x - start.x;
        int ydiff = end.y - start.y;
        int xadd = (int) ((double) xdiff / (double) div) * iter;
        int yadd = (int) ((double) ydiff / (double) div) * iter;
        int x = start.x + xadd;
        int y = start.y + yadd;
        return new Point(x, y);
    }

    public Point getLeftPointAt(int div, int iter) {
        Point start = this.p4;
        Point end = this.p1;
        int xdiff = end.x - start.x;
        int ydiff = end.y - start.y;
        int xadd = (int) ((double) xdiff / (double) div) * iter;
        int yadd = (int) ((double) ydiff / (double) div) * iter;
        int x = start.x + xadd;
        int y = start.y + yadd;
        return new Point(x, y);
    }

    public Point getRightPointAt(int div, int iter) {
        Point start = this.p3;
        Point end = this.p2;
        int xdiff = end.x - start.x;
        int ydiff = end.y - start.y;
        int xadd = (int) ((double) xdiff / (double) div) * iter;
        int yadd = (int) ((double) ydiff / (double) div) * iter;
        int x = start.x + xadd;
        int y = start.y + yadd;
        return new Point(x, y);
    }

    public static final Line getLine(Point p1, Point p2) {
        if (p1.x < p2.x) {
            return Quadrilateral.getLine(p2, p1);
        } else {
            int x1 = p1.x;
            int x2 = p2.x;
            int y1 = p1.y;
            int y2 = p2.y;
            int xdiff = x2 - x1;
            int ydiff = y2 - y1;
            double m = (double) ydiff / (double) xdiff;
            double b = y1 - m * x1;
            return new Line(m, b);
        }
    }

    public void paint(Graphics g, BufferedImage image) {
        int w = image.getWidth();
        int h = image.getHeight();
        Quadrilateral[][] grid = this.grid(w, h);
        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                g.setColor(new Color(image.getRGB(x, y), true));
                g.fillPolygon(grid[x][y]);
            }
        }
    }
}
导入java.awt.Color;
导入java.awt.Graphics;
导入java.awt.Point;
导入java.awt.Polygon;
导入java.awt.image.buffereImage;
导入java.util.ArrayList;
公共最终类四边形延伸多边形{
私有静态最终长serialVersionUID=794866732073166739L;
公共终点p1、p2、p3、p4;
公共终点线l12、l23、l34、l41;
公共四边形(点p1、点p2、点p3、点p4){
超级(新int[]{p1.x,p2.x,p3.x,p4.x},新int[]{p1.y,p2.y,
p3.y,p4.y},4);
这是1.p1=p1;
这是p2=p2;
这是p3=p3;
这是p4=p4;
this.l12=四边形.getLine(p1,p2);
this.l23=四边形.getLine(p2,p3);
this.l34=四边形.getLine(p3,p4);
this.l41=四边形.getLine(p4,p1);
}
公共静态四边形格式(四边形,int w,
int(h){
返回新的四边形(Format.Format(Quadrilateral.p1,w,h),
Format.Format(四边形.p2,w,h),Format.Format(
四边形。p3,w,h),Format.Format(
四边形(p4,w,h));
}
公共四边形[][]网格(整数x,整数y){
点[][]点=新点[x+1][y+1];

对于(int ix=0;ix我创建了一个完整的算法。它相当长。下面包含
四边形.java
文件。最后一种方法,
绘制(Graphics,BuffereImage)
修改图像并将其以自己的形状绘制到图形上:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

public final class Quadrilateral extends Polygon {
    private static final long serialVersionUID = 794866732073166739L;
    public final Point p1, p2, p3, p4;
    public final Line l12, l23, l34, l41;

    public Quadrilateral(Point p1, Point p2, Point p3, Point p4) {
        super(new int[] { p1.x, p2.x, p3.x, p4.x }, new int[] { p1.y, p2.y,
                p3.y, p4.y }, 4);
        this.p1 = p1;
        this.p2 = p2;
        this.p3 = p3;
        this.p4 = p4;
        this.l12 = Quadrilateral.getLine(p1, p2);
        this.l23 = Quadrilateral.getLine(p2, p3);
        this.l34 = Quadrilateral.getLine(p3, p4);
        this.l41 = Quadrilateral.getLine(p4, p1);
    }

    public static Quadrilateral formatted(Quadrilateral quadrilateral, int w,
            int h) {
        return new Quadrilateral(Format.format(quadrilateral.p1, w, h),
                Format.format(quadrilateral.p2, w, h), Format.format(
                        quadrilateral.p3, w, h), Format.format(
                        quadrilateral.p4, w, h));
    }

    public Quadrilateral[][] grid(int x, int y) {
        Point[][] points = new Point[x + 1][y + 1];
        for (int ix = 0; ix <= x; ix++) {
            for (int iy = 0; iy <= y; iy++) {
                points[ix][iy] = this.getPointAt(x, y, ix, iy);
            }
        }
        Quadrilateral[][] qs = new Quadrilateral[x][y];
        for (int ix = 0; ix < x; ix++) {
            for (int iy = 0; iy < y; iy++) {
                qs[ix][iy] = new Quadrilateral(points[ix][iy],
                        points[ix + 1][iy], points[ix + 1][iy + 1],
                        points[ix][iy + 1]);
            }
        }
        return qs;
    }

    public ArrayList<ArrayList<Quadrilateral>> gridList(int x, int y) {
        Point[][] points = new Point[x + 1][y + 1];
        for (int ix = 0; ix <= x; ix++) {
            for (int iy = 0; iy <= y; iy++) {
                points[ix][iy] = this.getPointAt(x, y, ix, iy);
            }
        }
        ArrayList<ArrayList<Quadrilateral>> qs = new ArrayList<>(0);
        for (int ix = 0; ix < x; ix++) {
            qs.add(new ArrayList<>(y));
            for (int iy = 0; iy < y; iy++) {
                qs.get(ix).add(
                        new Quadrilateral(points[ix][iy], points[ix + 1][iy],
                                points[ix + 1][iy + 1], points[ix][iy + 1]));
            }
        }
        return qs;
    }

    public Point getPointAt(int xdiv, int ydiv, int xiter, int yiter) {
        Point n1 = this.getTopPointAt(xdiv, xiter);
        Point n2 = this.getRightPointAt(ydiv, yiter);
        Point n3 = this.getBottomPointAt(xdiv, xiter);
        Point n4 = this.getLeftPointAt(ydiv, yiter);
        Line h = Quadrilateral.getLine(n4, n2);
        Line v = Quadrilateral.getLine(n1, n3);
        return h.intersect(v, n2.x, n1.x);
    }

    public Point getTopPointAt(int div, int iter) {
        Point start = this.p1;
        Point end = this.p2;
        int xdiff = end.x - start.x;
        int ydiff = end.y - start.y;
        int xadd = (int) ((double) xdiff / (double) div) * iter;
        int yadd = (int) ((double) ydiff / (double) div) * iter;
        int x = start.x + xadd;
        int y = start.y + yadd;
        return new Point(x, y);
    }

    public Point getBottomPointAt(int div, int iter) {
        Point start = this.p4;
        Point end = this.p3;
        int xdiff = end.x - start.x;
        int ydiff = end.y - start.y;
        int xadd = (int) ((double) xdiff / (double) div) * iter;
        int yadd = (int) ((double) ydiff / (double) div) * iter;
        int x = start.x + xadd;
        int y = start.y + yadd;
        return new Point(x, y);
    }

    public Point getLeftPointAt(int div, int iter) {
        Point start = this.p4;
        Point end = this.p1;
        int xdiff = end.x - start.x;
        int ydiff = end.y - start.y;
        int xadd = (int) ((double) xdiff / (double) div) * iter;
        int yadd = (int) ((double) ydiff / (double) div) * iter;
        int x = start.x + xadd;
        int y = start.y + yadd;
        return new Point(x, y);
    }

    public Point getRightPointAt(int div, int iter) {
        Point start = this.p3;
        Point end = this.p2;
        int xdiff = end.x - start.x;
        int ydiff = end.y - start.y;
        int xadd = (int) ((double) xdiff / (double) div) * iter;
        int yadd = (int) ((double) ydiff / (double) div) * iter;
        int x = start.x + xadd;
        int y = start.y + yadd;
        return new Point(x, y);
    }

    public static final Line getLine(Point p1, Point p2) {
        if (p1.x < p2.x) {
            return Quadrilateral.getLine(p2, p1);
        } else {
            int x1 = p1.x;
            int x2 = p2.x;
            int y1 = p1.y;
            int y2 = p2.y;
            int xdiff = x2 - x1;
            int ydiff = y2 - y1;
            double m = (double) ydiff / (double) xdiff;
            double b = y1 - m * x1;
            return new Line(m, b);
        }
    }

    public void paint(Graphics g, BufferedImage image) {
        int w = image.getWidth();
        int h = image.getHeight();
        Quadrilateral[][] grid = this.grid(w, h);
        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                g.setColor(new Color(image.getRGB(x, y), true));
                g.fillPolygon(grid[x][y]);
            }
        }
    }
}
导入java.awt.Color;
导入java.awt.Graphics;
导入java.awt.Point;
导入java.awt.Polygon;
导入java.awt.image.buffereImage;
导入java.util.ArrayList;
公共最终类四边形延伸多边形{
私有静态最终长serialVersionUID=794866732073166739L;
公共终点p1、p2、p3、p4;
公共终点线l12、l23、l34、l41;
公共四边形(点p1、点p2、点p3、点p4){
超级(新int[]{p1.x,p2.x,p3.x,p4.x},新int[]{p1.y,p2.y,
p3.y,p4.y},4);
这是1.p1=p1;
这是p2=p2;
这是p3=p3;
这是p4=p4;
this.l12=四边形.getLine(p1,p2);
this.l23=四边形.getLine(p2,p3);
this.l34=四边形.getLine(p3,p4);
this.l41=四边形.getLine(p4,p1);
}
公共静态四边形格式(四边形,int w,
int(h){
返回新的四边形(Format.Format(Quadrilateral.p1,w,h),
Format.Format(四边形.p2,w,h),Format.Format(
四边形。p3,w,h),Format.Format(
四边形(p4,w,h));
}
公共四边形[][]网格(整数x,整数y){
点[][]点=新点[x+1][y+1];

对于(int ix=0;ix,这取决于您对“剪切”的了解。对于我来说,现在离睡觉时间太近,无法公开上传代码,但您可以创建一个带有剪切坐标的多边形,并使用fillPolygon()或类似的工具。对于倾斜/剪切,我使用
AffineTransform.shear(双x,双y)
@jamesmith:不,我不相信你上面的说法是正确的,我也不相信仅仅用仿射变换就足够了。仿射变换在数学上不能倾斜,因为在它下面,平行线在这种类型的变换后必须保持平行。我的术语不正确:变换可以倾斜,变换that保留了平行线,但它不能如上图所示——它不能将平行线更改为非平行线。C#有一种称为QuadTexture的东西,它允许您这样做。它是一个外部库。我猜您可能能够转换代码?我知道这比您希望的更痛苦,这取决于什么你有关于“剪切”的信息。现在离睡觉时间太近了,我无法公开上传代码,但你可以做的是创建一个带有剪切坐标的多边形,然后使用fillPolygon()或类似的东西。对于倾斜/剪切,我使用
AffineTransform.shear(双x,双y)
@jamesmith:不,我不相信你上面的说法是正确的,我也不相信仅仅用仿射变换就足够了。仿射变换在数学上不能倾斜,因为在它下面,平行线在这种类型的变换后必须保持平行。我的术语不正确:变换可以倾斜,变换that保留平行线,但它不能如上图所示——它不能将平行线更改为非平行线。C#有一种称为QuadTexture的东西,它允许您这样做。它是一个外部库。我猜您可能能够转换代码?我知道这比您希望的更痛苦