2013-02-25 79 views
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(); 
} 

當我運行此我得到的形式如下(請注意,這不是我的正常的圖像) :

Before Rotation

這幾乎是我想除了它不顯示的透明藍色的背景是什麼。但是,如果我旋轉圖像的藍色顯示:

After Rotation

+0

好,爲更好地幫助更快張貼[SSCCE(http://sscce.org/),短,可運行,編譯,否則這個問題是不應答的, – mKorbel 2013-02-25 09:08:22

+1

1-不要使用panel.getGraphics。 2-確保您已將面板設置爲透明(setOpaque(false)),請記住,您現在負責以半透明的藍色填充組件的背景 – MadProgrammer 2013-02-25 09:10:09

+2

不要調用repaint()in '的paintComponent()'。這是創造一個無限循環! – 2013-02-25 09:19:24

回答

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

只要運行這個,看看結果: enter image description here

也有一些代碼爲什麼你應該或不應該做些什麼的意見。
請確保您仔細閱讀。

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

enter image description here