2

我一直在研究一个程序,该程序涉及在透明表单上旋转部分透明的图像。图像的绘制最初效果很好,我还将自定义面板的背景颜色设置为透明的浅蓝色,效果也很好。当我尝试旋转图像时,我的问题就开始了。

为了旋转它,我必须将 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();
}

当我运行它时,我得到如下表格(请注意,这不是我的正常图像):

旋转前

这几乎是我想要的,除了它不显示透明的蓝色背景。但是,如果我旋转图像,蓝色显示:

旋转后

4

2 回答 2

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

只需运行它并查看结果: 在此处输入图像描述

还有一些关于代码的注释为什么你应该或不应该做某事。
确保您仔细阅读它们。

于 2013-02-25T10:39:18.150 回答
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();
                }
            }
        });
    }
}

在此处输入图像描述

于 2013-02-25T11:43:25.467 回答