How to render tilted images in Java?
My problem is I have a Java application that renders an image. Now I want to render a tilted image.
One straightforward approach would be to have a tilted image开发者_如何学JAVA and then render it, but my aim is to tilt the image according to the mouse movement in the window.
One possible solution for this would be to have multiple images at various tilted angles and render them as the mouse moves, but such an implementation is limited in precision and not quite the thing I want.
Is there a way to render the tilted image on the fly?
Thanks in advance.
I agree completely with the previous post, AffineTransform is the way to go. Here's a simple example....
import java.awt.*;
import java.awt.geom.*;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;
public class RotateImage {
private static final int PANEL_WIDTH = 600;
private static final Dimension MAIN_SIZE = new Dimension(PANEL_WIDTH, PANEL_WIDTH);
private static final int SLIDER_MIN = -180;
private static final int SIDER_MAX = 180;
private static final int MAJOR_TICK = 30;
private static final int MINOR_TICK = 15;
private static final String URL_PATH = "http://duke.kenai.com/guitar/DukeAsKeith-daylightSmall.png";
private JPanel mainPanel = new JPanel();
private JPanel drawingPanel = createDrawingPanel();
private AffineTransform transform = new AffineTransform();
private JSlider rotationSlider;
private Image image;
public RotateImage() {
mainPanel.setLayout(new BorderLayout());
mainPanel.add(drawingPanel, BorderLayout.CENTER);
mainPanel.add(createTransformPanel(), BorderLayout.SOUTH);
URL url;
try {
url = new URL(URL_PATH);
image = ImageIO.read(url );
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private JPanel createTransformPanel() {
rotationSlider = new JSlider(SLIDER_MIN, SIDER_MAX, 0);
rotationSlider.setMajorTickSpacing(MAJOR_TICK);
rotationSlider.setMinorTickSpacing(MINOR_TICK);
rotationSlider.setPaintLabels(true);
rotationSlider.setPaintTicks(true);
rotationSlider.setPaintTrack(true);
rotationSlider.setSnapToTicks(true);
rotationSlider.addChangeListener(new SliderListener());
JPanel transformingPanel = new JPanel(new BorderLayout());
transformingPanel.setBorder(BorderFactory.createEtchedBorder());
transformingPanel.add(rotationSlider);
return transformingPanel;
}
@SuppressWarnings("serial")
private JPanel createDrawingPanel() {
if (drawingPanel != null) {
return drawingPanel;
}
drawingPanel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
myPaint(g);
}
};
drawingPanel.setPreferredSize(MAIN_SIZE);
return drawingPanel;
}
private void myPaint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(3));
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
AffineTransform oldTransform = g2.getTransform();
if (transform != null) {
g2.setTransform(transform);
}
if (image != null) {
g2.drawImage(image, 70, 70, null);
}
g2.setTransform(oldTransform);
}
public JComponent getPanel() {
return mainPanel;
}
private class SliderListener implements ChangeListener {
public void stateChanged(ChangeEvent e) {
double theta = Math.PI * rotationSlider.getValue() / 180;
double center = (double) PANEL_WIDTH / 2;
transform = AffineTransform.getRotateInstance(theta, center, center);
drawingPanel.repaint();
}
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("RotateShape Application");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new RotateImage().getPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
I think you need to look into AffineTransform it has a method for rotating a shape, as well as other transforms.
An example of how it can be used can be found here
Basically:
AffineTransform at = AffineTransform.getTranslateInstance(width, height); //Create the AffineTransform instance
at.rotate(someRadianValue); // Apply the transforms you wish
g2.draw(at.createTransformedShape(myShape)); // Draw the transformed shape
精彩评论