当前位置: 首页 > 面试题库 >

反向Java Graphics2D缩放和旋转坐标

冯福
2023-03-14
问题内容

我使用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;
}


 类似资料:
  • 我有一个被JScrollPane包围的JPanel。该JPanel用于显示图像。我需要提供zoomIn、zoomOut、顺时针旋转和逆时针旋转等功能。所有这些功能单独运行良好。对于缩放,我称之为图形对象的缩放。它发生在从左上到右下的基础上。对于旋转,我重置比例,然后平移、旋转 因此,问题是当面板坐标更改时,图像的坐标不会改变。有人可以帮助我更改图像的坐标吗?

  • 选择要变换的文字 您可以像对其他对象一样,对文字进行旋转、镜像、比例缩放和倾斜。但是,您选择文字的方式会影响变换结果: 要变换文字及其边框路径,请选择文字对象,然后使用旋转工具旋转对象和文本。 要只变换边框路径(而不变换它所包含的文字),请使用选择工具选择文字对象并进行拖移。 旋转文字路径(左图)与旋转文字和路径(右图)的对比图 另请参阅 第 197 页的 “变换对象 ” 调整文字缩放比例 您可以

  • 我有不同维度的文档图像,我希望能够有效地缩放和旋转他们在以下方式(标准的“旋转”和“缩放”逻辑)。我怎么做? 一幅图像是H像素高,W像素宽。最初,它应该缩放到600像素宽。在每次旋转时,面板的宽度和高度应该互换,缩放图像应该旋转90度。在每次缩放时,图像应按因子“比例”缩放。 以下是我到目前为止在...得到的BufferedImage会缩放和旋转,但不会平移(旋转90度后位于面板顶部的中心):

  • 选择要变换的文字 您可以像对其他对象一样,对文字进行旋转、镜像、比例缩放和倾斜。但是,您选择文字的方式会影响变换结果: 要变换文字及其边框路径,请选择文字对象,然后使用旋转工具旋转对象和文本。 要只变换边框路径(而不变换它所包含的文字),请使用选择工具选择文字对象并进行拖移。旋转文字路径(左图)与旋转文字和路径(右图)的对比图 调整文字缩放比例 您可以相对字符的原始宽度和高度,指定文字高度和宽度的

  • 我有下面的代码,它做(第一部分)什么我想画一个棋盘上有一些棋子。 也就是说,它得到一个棋子的图像和图像的高度,它将图像的绘制转换为棋子所在的正方形,并将图像缩放到正方形的大小。 假设我想把黑色的部分旋转180度。我希望在某个地方有这样的东西: 如果我进入SmallChessboardComponent并从第一个rotation transform语句中删除注释delims,我将rook颠倒在原来的

  • 我正在尝试将鼠标点击坐标转换为画布坐标。画布可以动态缩放。我实现了缩放功能,缩放转换整个画布。画布本身有一个图像作为窗口的背景。当用户使用鼠标滚轮时,背景会放大和缩小。如何转换鼠标点击坐标以反映图像上的缩放位置? 缩放地图图像代码: 将图标添加到地图图像: 我基本上是想用鼠标左键在地图上添加一个新的图标图像。但是,如果在我尝试添加图标时放大了地图,则图像的位置与单击的地图位置不相关。它会转到离鼠标