Question

J'utilise Graphics2D en Java à l'échelle et faire pivoter l'image que je dessine. Je veux maintenant être en mesure de dire quelles sont les coordonnées d'origine étaient quand je clique sur un certain point dans l'image. Donc, étant donné les coordonnées pivotés et mis à l'échelle que je veux calculer les originaux. Est-il un moyen simple de le faire?

Était-ce utile?

La solution

Si vous gardez une copie de la AffineTransform que vous utilisez lorsque vous peignez l'image, vous pouvez utiliser   AffineTransform.inverseTransform (Point2D ptSrc, Point2D ptDst) à transformer un espace de coordonnées dispositif vers l'espace utilisateur

Modifier : Si vous capturez la transformation actuelle du Graphics2D en peinture, méfiez-vous de la Graphics2D être réutilisée pour plusieurs enfants légers de la même fenêtre / panneau, car alors la transformation sera relative au composant parent mais les coordonnées de la souris seront par rapport à l'enfant. Vous devez saisir les changements que vous apportez à la transformation non sa valeur finale. Exemple:

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;
}

Autres conseils

On ne sait pas exactement comment vous êtes en rotation et mise à l'échelle. Mais vous utilisez probablement AffineTransform . Heureusement, il y a un createInverse () méthode et a inverseTransform () méthode de .

Ainsi, votre code peut être

AffineTransform transform = AffineTransform.rotate(theta);
transform.scale(sx, sy);

Alors inverser, vous pouvez dire

Point2D pointInOrigCoords = transform.inverseTransform(clickPoint,null);

Son pas si difficile; -)

  1. Lorsque vous repeindre le composant sauver le AffineTransform après la transformante avec g2.getTransform()

  2. Ensuite, appelez la fonction invert() sur elle

  3. En cas de mouseClicked() nous le code suivant:

    Point2D p= trans.transform(new Point2D.Double(evt.getX(), evt.getY()), null);
    System.out.println("click x="+p.getX()+" y="+p.getY());
    

Thats it!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top