[英]Reverse Java Graphics2D scaled and rotated coordinates
我在Java中使用Graphics2D来缩放和旋转我绘制的图片。 我现在希望能够在我点击图片中的某个点时告诉原始坐标是什么。 因此,考虑到旋转和缩放的坐标,我想计算原始坐标。 有一个简单的方法吗?
如果保留绘制图像时使用的AffineTransform
的副本,则可以使用AffineTransform.inverseTransform(Point2D ptSrc,Point2D ptDst)将设备空间坐标转换回用户空间
编辑 :如果在绘制时捕获Graphics2D
的当前变换,请注意Graphics2D
被重用于同一窗口/面板的多个轻量级子项,因为那时变换将相对于父组件,但鼠标坐标将是相对于孩子。 您需要捕获对变换所做的更改而不是其最终值。 例:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class Main {
public static void main(String[] args) throws MalformedURLException, IOException {
JFrame frame = new JFrame();
Box box = new Box(BoxLayout.Y_AXIS);
BufferedImage image = ImageIO.read(new URL("http://sstatic.net/so/img/logo.png"));
AffineTransform xfrm1 = AffineTransform.getScaleInstance(0.95, 1.25);
xfrm1.rotate(-0.3);
box.add(new ImageView(image, xfrm1));
AffineTransform xfrm2 = AffineTransform.getShearInstance(0.1, 0.2);
xfrm2.scale(1.3, 0.9);
box.add(new ImageView(image, xfrm2));
frame.add(box);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
@SuppressWarnings("serial")
class ImageView extends JComponent {
@Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
try {
paintXfrm = g2d.getTransform();
paintXfrm.invert();
g2d.translate(getWidth() / 2, getHeight() / 2);
g2d.transform(xfrm);
g2d.translate(image.getWidth() * -0.5, image.getHeight() * -0.5);
paintXfrm.concatenate(g2d.getTransform());
g2d.drawImage(image, 0, 0, this);
} catch (NoninvertibleTransformException ex) {
ex.printStackTrace();
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(image.getWidth() * 2, image.getHeight() * 2);
}
ImageView(final BufferedImage image, final AffineTransform xfrm) {
this.canvas = image.createGraphics();
canvas.setColor(Color.BLACK);
canvas.setStroke(new BasicStroke(3.0f));
this.image = image;
this.xfrm = xfrm;
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
try {
mouseDownCoord = e.getPoint();
paintXfrm.inverseTransform(mouseDownCoord, mouseDownCoord);
} catch (NoninvertibleTransformException ex) {
}
}
@Override
public void mouseExited(MouseEvent e) {
mouseDownCoord = null;
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
Point p = e.getPoint();
try {
paintXfrm.inverseTransform(p, p);
if (mouseDownCoord != null) {
canvas.drawLine(mouseDownCoord.x, mouseDownCoord.y, p.x, p.y);
for (Component sibling: getParent().getComponents()) {
sibling.repaint();
}
}
mouseDownCoord = p;
} catch (NoninvertibleTransformException ex) {
ex.printStackTrace();
}
}
});
}
private Graphics2D canvas;
private BufferedImage image;
private AffineTransform xfrm;
private AffineTransform paintXfrm;
private Point mouseDownCoord;
}
目前尚不清楚你是如何旋转和缩放的。 但是你可能正在使用AffineTransform 。 幸运的是,有一个createInverse()方法和一个inverseTransform()方法。
所以你的代码可能是
AffineTransform transform = AffineTransform.rotate(theta);
transform.scale(sx, sy);
然后反转,你可以说
Point2D pointInOrigCoords = transform.inverseTransform(clickPoint,null);
它不那么难;-)
重新绘制组件后,使用g2.getTransform()
转换后保存AffineTransform
然后调用函数invert()
就可以了
在mouseClicked()
事件中我们使用以下代码:
Point2D p= trans.transform(new Point2D.Double(evt.getX(), evt.getY()), null); System.out.println("click x="+p.getX()+" y="+p.getY());
而已!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.