我一直在研究一个涉及在透明表格上旋转部分透明图像的程序。最初的图像绘制工作正常,我还将自定义面板的背景颜色设置为透明浅蓝色,这也很好。当我尝试旋转图像时,我的问题开始了。
为了旋转它,我必须将panel.getGraphics()转换为Graphics2D。当我这样做时,透明度消失了,所以我完成了我的旋转代码,然后阅读了透明度。我发现我可以设置Graphics2D的组合,这正是我在这里看到的:
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));
g2d.setColor(new Color(0, 0, 200, 90));
g2d.fillRect(0, 0, this.getWidth(), this.getHeight());
g2d.rotate(radians);
g2d.drawImage(img, 0, 0, null);
repaint();
}
当我运行时,我得到如下表格(请注意,这不是我的正常形象):
这几乎是我想要的,除了它没有显示透明的蓝色背景。但是,如果我旋转图像,则蓝色显示:
答案 0 :(得分:2)
问题部分在您指定的复合材料中:AlphaComposite.SRC
我真的不知道你用它做了什么,但它覆盖了源像素数据。这就是为什么当图像被涂在上面时,面板背景会被覆盖。
如果您还没有阅读,我建议您阅读有关图形复合的内容: http://docs.oracle.com/javase/tutorial/2d/advanced/compositing.html
无论如何,请看示例如何做类似的事情:
(这只是其中一种可能性 - 你可以用其他十种方式做到这一点)
public class SmileyTest
{
private static Color bg = new Color ( 0, 0, 255, 128 );
private static float angle = 0f;
public static void main ( String[] args )
{
final ImageIcon icon = new ImageIcon ( SmileyTest.class.getResource ( "icons/smiley.png" ) );
JDialog frame = new JDialog ();
frame.setLayout ( new BorderLayout () );
// We should not use default background and opaque panel - that might cause repaint problems
// This is why we use JPanel with transparent background painted and opacity set to false
JPanel transparentPanel = new JPanel ( new BorderLayout () )
{
protected void paintComponent ( Graphics g )
{
super.paintComponent ( g );
g.setColor ( bg );
g.fillRect ( 0, 0, getWidth (), getHeight () );
}
};
transparentPanel.setOpaque ( false );
frame.add ( transparentPanel );
// Image in another component
final JComponent component = new JComponent ()
{
protected void paintComponent ( Graphics g )
{
super.paintComponent ( g );
Graphics2D g2d = ( Graphics2D ) g;
// For better image quality when it is rotated
g2d.setRenderingHint ( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR );
// Rotating area using image middle as rotation center
g2d.rotate ( angle * Math.PI / 180, getWidth () / 2, getHeight () / 2 );
// Transparency for image
g2d.setComposite ( AlphaComposite.getInstance ( AlphaComposite.SRC_OVER, 0.5f ) );
// Draing image
g2d.drawImage ( icon.getImage (), 0, 0, null );
}
};
transparentPanel.add ( component );
// Rotation animation (24 frames per second)
new Timer ( 1000 / 48, new ActionListener ()
{
public void actionPerformed ( ActionEvent e )
{
angle += 0.5f;
component.repaint ();
}
} ).start ();
frame.setUndecorated ( true );
AWTUtilities.setWindowOpaque ( frame, false );
frame.setSize ( icon.getIconWidth (), icon.getIconHeight () );
frame.setLocationRelativeTo ( null );
frame.setVisible ( true );
}
}
运行此命令并查看结果:
还有一些关于代码的评论,为什么你应该或不应该做什么 请务必仔细阅读。
答案 1 :(得分:0)
另一种方法:
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class TestTransparentRotatedImage {
private static class TransparentRotatedImage extends JPanel {
private final Image image;
private double rotation;
public TransparentRotatedImage(Image image) {
this.image = image;
setOpaque(false);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
g2.setColor(new Color(0, 0, 200, 90));
g2.fillRect(0, 0, getWidth(), getHeight());
g2.setTransform(getTransformation());
g2.drawImage(image, 0, 0, this);
}
protected AffineTransform getTransformation() {
try {
AffineTransform translateInstance = AffineTransform.getTranslateInstance(+image.getWidth(this) / 2,
+image.getWidth(this) / 2);
AffineTransform inverse = translateInstance.createInverse();
AffineTransform rotateInstance = AffineTransform.getRotateInstance(Math.toRadians(rotation));
AffineTransform at = translateInstance;
at.concatenate(rotateInstance);
at.concatenate(inverse);
return at;
} catch (NoninvertibleTransformException e) {
e.printStackTrace();
return null;
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(image.getWidth(this), image.getHeight(this));
}
public void setRotation(double rotation) {
this.rotation = rotation;
repaint();
}
}
protected void initUI() throws MalformedURLException {
final JFrame frame = new JFrame(TestTransparentRotatedImage.class.getSimpleName());
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
frame.getContentPane().setBackground(new Color(0, 0, 0, 0));
// com.sun.awt.AWTUtilities.setWindowOpacity(frame, 0);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final TransparentRotatedImage rotatedImage = new TransparentRotatedImage(new ImageIcon(new URL(
"http://files.myopera.com/supergreatChandu8/albums/5466862/smiley-transparent.png")).getImage());
frame.add(rotatedImage);
final JSlider slider1 = new JSlider(0, 360);
slider1.setValue(0);
slider1.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
rotatedImage.setRotation(slider1.getValue());
}
});
frame.add(slider1, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
new TestTransparentRotatedImage().initUI();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}