2010-02-11 25 views
6

Tôi sử dụng Graphics2D trong Java để chia tỷ lệ và xoay hình ảnh tôi vẽ. Bây giờ tôi muốn có thể cho biết tọa độ ban đầu là gì khi tôi nhấp vào một điểm nhất định trong hình ảnh. Vì vậy, cho các tọa độ xoay và thu nhỏ, tôi muốn tính toán các tọa độ ban đầu. Có một cách đơn giản để làm điều này?Đảo ngược Java Graphics2D điều chỉnh tỷ lệ và xoay

+0

Điều này sẽ giúp http://stackoverflow.com/questions/11821381/cant-get-my-coordinates-graphics2d-mouseclick-java – pknoe3lh

Trả lời

8

Nếu bạn giữ một bản sao của AffineTransform bạn sử dụng khi bạn vẽ hình ảnh, bạn có thể sử dụng AffineTransform.inverseTransform(Point2D ptSrc, Point2D ptDst) để biến đổi một không gian thiết bị phối hợp lại để sử dụng không gian

Sửa: Nếu bạn nắm bắt được hiện chuyển đổi của Graphics2D trong khi vẽ, hãy cẩn thận với Graphics2D được tái sử dụng cho nhiều trẻ em nhẹ cùng cửa sổ/bảng điều khiển, vì sau đó biến đổi sẽ liên quan đến thành phần gốc nhưng tọa độ chuột sẽ liên quan đến trẻ. Bạn cần nắm bắt các thay đổi mà bạn thực hiện đối với biến đổi không phải giá trị cuối cùng của nó. Ví dụ:

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

Ví dụ liên quan được hiển thị [tại đây] (https://stackoverflow.com/a/44388407/230513). – trashgod

3

Không rõ chính xác cách bạn xoay và nhân rộng. Nhưng có thể bạn đang sử dụng một số AffineTransform. May mắn thay, có một phương pháp createInverse() và phương thức inverseTransform().

Vì vậy, mã của bạn có thể là

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

Sau đó, để đảo ngược, bạn có thể nói

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

của nó không khó khăn như vậy ;-)

  1. Khi bạn sơn lại các phần tiết kiệm số AffineTransform sau khi chuyển đổi với g2.getTransform()

  2. Sau đó gọi hàm invert() vào nó

  3. Trong trường hợp chúng tôi mouseClicked() đoạn mã sau:

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

Thats nó!