我想旋转BufferedImage
和内部显示它JLabel
(这是一个内部JPanel
)。 当前结果产生白色正方形旋转10度在黑色背景,但图像不存在的正方形内。 我知道myPicture
不为空,因为myPicture
本身正常显示里面JPanel
不旋转时。
下面是代码:
int w = myPicture.getWidth();
int h = myPicture.getHeight();
BufferedImage newImage = new BufferedImage(w, h, myPicture.getType());
Graphics2D graphic = newImage.createGraphics();
graphic.rotate(Math.toRadians(10), w/2, h/2);
graphic.drawImage(myPicture, null, 0, 0);
picLabel.setIcon(new ImageIcon(newImage));
这里没有很多去,但两件事情浮现在脑海中。 这有可能是图像没有在正确的位置上渲染它的旋转后和两个,你不处置的的Graphics
,当你与它(不,我认为它应该有一个效果做背景,但你永远不知道)。
这是一个简单的例子呈现经由结果paintComponent
,但概念是相同的。
它使用AffineTransformation
旋转图像。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class TestRotateImage {
public static void main(String[] args) {
new TestRotateImage();
}
public TestRotateImage() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JSlider slider;
private BufferedImage image;
public TestPane() {
setLayout(new BorderLayout());
try {
image = ImageIO.read(new File("/path/to/your/image"));
} catch (IOException ex) {
ex.printStackTrace();
}
slider = new JSlider();
slider.setMinimum(0);
slider.setMaximum(360);
slider.setMinorTickSpacing(5);
slider.setMajorTickSpacing(10);
slider.setValue(0);
add(slider, BorderLayout.SOUTH);
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
repaint();
}
});
}
@Override
public Dimension getPreferredSize() {
return image == null ? new Dimension(200, 200) : new Dimension(image.getWidth(), image.getHeight());
}
public double getAngle() {
return Math.toRadians(slider.getValue());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
g2d.drawLine(getWidth() / 2, 0, getWidth() / 2, getHeight());
g2d.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2);
g2d.setColor(Color.BLACK);
int x = (getWidth() - image.getWidth()) / 2;
int y = (getHeight() - image.getHeight()) / 2;
AffineTransform at = new AffineTransform();
at.setToRotation(getAngle(), x + (image.getWidth() / 2), y + (image.getHeight() / 2));
at.translate(x, y);
g2d.setTransform(at);
g2d.drawImage(image, 0, 0, this);
g2d.dispose();
}
}
}
更新使用一个JLabel
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class TestRotateImage {
public static void main(String[] args) {
new TestRotateImage();
}
public TestRotateImage() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JSlider slider;
private BufferedImage image;
private JLabel label;
public TestPane() {
setLayout(new BorderLayout());
label = new JLabel();
label.setHorizontalAlignment(JLabel.CENTER);
label.setVerticalAlignment(JLabel.CENTER);
try {
image = ImageIO.read(new File("/path/to/your/image"));
label.setIcon(new ImageIcon(image));
} catch (IOException ex) {
ex.printStackTrace();
}
add(label);
slider = new JSlider();
slider.setMinimum(0);
slider.setMaximum(360);
slider.setMinorTickSpacing(5);
slider.setMajorTickSpacing(10);
slider.setValue(0);
add(slider, BorderLayout.SOUTH);
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
double radians = Math.toRadians(slider.getValue());
double sin = Math.abs(Math.sin(radians));
double cos = Math.abs(Math.cos(radians));
int newWidth = (int)Math.round(image.getWidth() * cos + image.getHeight() * sin);
int newHeight = (int)Math.round(image.getWidth() * sin + image.getHeight() * cos);
BufferedImage rotate = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = rotate.createGraphics();
int x = (newWidth - image.getWidth()) / 2;
int y = (newHeight - image.getHeight()) / 2;
AffineTransform at = new AffineTransform();
at.setToRotation(getAngle(), x + (image.getWidth() / 2), y + (image.getHeight() / 2));
at.translate(x, y);
g2d.setTransform(at);
g2d.drawImage(image, 0, 0, TestPane.this);
g2d.dispose();
label.setIcon(new ImageIcon(rotate));
}
});
}
@Override
public Dimension getPreferredSize() {
return image == null ? new Dimension(200, 200) : new Dimension(image.getWidth(), image.getHeight());
}
public double getAngle() {
return Math.toRadians(slider.getValue());
}
}
}
我解决我自己的问题。 这个问题在代码居士:
myPicture.getType()
由于有大量的图像类型的变化,你可以把在该程序中,结果会当你开始绘制到新的BufferedImage是不可预知的。 我通过显式设置的类型,这在我的情况下,需要解决的问题
BufferedImage.TYPE_INT_ARGB
因此,声明全文如下:
BufferedImage newImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);