如何在Java中获得Shape of AfineTransform旋转图像

时间:2019-04-17 13:23:35

标签: java image rotation shapes

我能够旋转图像。这很好。但是,我希望能够提取结果图像的形状/多边形,以便当鼠标移过旋转的图像时可以使用它捕获鼠标事件。

这是我的代码:

private Shape imageShape;

private Image rotateFilter(Image img, int degrees) {
    BufferedImage sourceImage = (BufferedImage)img;

    double radians = Math.toRadians(degrees);
    double cos = Math.abs(Math.cos(radians));
    double sin = Math.abs(Math.sin(radians));

    int width = sourceImage.getWidth();
    int height = sourceImage.getHeight();

    int w = (int) Math.floor(width * cos + height * sin);
    int h = (int) Math.floor(width * sin + height * cos);

    int x = (w - width) / 2;
    int y = (h - height) / 2;

    BufferedImage destImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);        
    Graphics2D g2d = destImage.createGraphics();

    AffineTransform at = new AffineTransform();
    at.rotate(radians, x + (width / 2), y + (height / 2));
    at.translate(x, y);

以某种方式在此处获得Shape / Polygon(imageShape)         g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC);         g2d.drawRenderedImage(sourceImage,at);         g2d.dispose();         返回destImage;     }

public void mouseEntered(MouseEvent e) {
    int mx = e.getX();
    int my = e.getY();
    return imageShape.contains(mx, my);
}

3 个答案:

答案 0 :(得分:0)

是的,很遗憾,没有简单的方法。如果旋转图像,仍然会得到一个矩形,其中旋转了图像。我唯一能够解决的方法是使用数学方法管理4个角,但是当然,数学永远不会与AffineTransform旋转完全相同。

我想要做的是旋转图像并对其应用形状,以便可以用x / y鼠标使用contains()。我只希望鼠标在图像上的实际位置上接收事件,即使它旋转了。

答案 1 :(得分:0)

执行此操作的方法有多种-除了您建议的直接数学之外,还必须将其应用于变换矩阵,并且要在同一侧:

a)使用点并将其转换:

    AffineTransform at=AffineTransform.getRotateInstance(....);
    Point p=new Point(x, y);
    at.transform(p, p);

这将变换点p并将结果存储到其自身上,因此p会发生变化-您可以使用另一个点来存储新坐标。

应用于四个点,然后创建多边形

Polygon pl=new Polygon();
for(i=0; i<points.length; i+++) pl.addPoint(points[i].x, points[i].y);

多边形具有contains()方法。

b)从原始图像创建多边形(或矩形)

Polygon pl=new Polygon();
pl.addPoint(0, 0);
pl.addPoint(im.getWidth()-1, 0);
pl.addPoint(im.getWidth()-1, im.getHeight()-1);
pl.addPoint(0, im.getHeight()-1);

Rectangle r=new Rectangle(0, 0, im.getWidth(), im.getHeight());

然后使用

  AffineTransform at=new AffineTransform(.....);
  Shape sh=at.createTransformedShape(pl);

并使用sh作为新形状。这个东西并不总是能准确地工作(我的意思是整个东西都有形状,边界等),但是如果您正在寻找它,那将会很方便。

答案 2 :(得分:0)

是的,我几乎完全使用了您的选项B。我这样做的方法是存储两个矩形。一个用于存储旋转/变换后的图像的x,y,w,h,另一个用于存储一组原始图像x,y,w,h。后一个矩形不会改变(嗯,至少要等到我缩放后,此矩形才会更新)。由于后者不会改变,因此我将其用于记录“真实”图像,而不是转换后的图像。因此,我们要做的是affineTransform图像,然后完全按照您的建议构建多边形,然后使用createTrasformedShape获取形状。如此钉在钉子上。它真的很好。有点慢,但非常准确。谢谢。