在Java Graphics2D中绘制透明图像

时间:2011-11-25 17:43:24

标签: java transparent graphics2d

我想在另一个上面绘制一个部分透明的图像(在物体上制作阴影)。我目前正在使用java的Graphics2D类进行渲染,我被告知将复合设置为AlphaComposite,但这只是将它设置为完全透明。

我可以使用当前设置执行此操作吗?我该怎么做才能解决这个问题?

这是我被告知会使其部分透明的代码:

    AlphaComposite ac = java.awt.AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.5F);
    g.setComposite(ac);

(我顺便使用png图像)

继承你的sscce(这些都是在不同的类中,但为了简单起见我把它们放在一起)(我使用一个名为&#34的图像;测试"在本地文件夹"图像",你可以只要它是一个名为相同的png图像

,就可以使用任何东西
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.DisplayMode;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Window;

import javax.swing.ImageIcon;

import com.blazingkin.atrox.ScreenManager;

public class AtroxAdventrum{

public static void main(String[] args) {
new AtroxAdventrum().run();
}

    private static DisplayMode modes[] = {

        //new DisplayMode(1080,720,32,0),
        //new DisplayMode(1080,720,24,0),
        //new DisplayMode(1080,720,16,0),
        //new DisplayMode(1440,900,32,0),
        //new DisplayMode(1440,900,24,0),
        //new DisplayMode(1440,900,16,0),

    };
    private boolean running = true;
    public ScreenManager s;

    public void stop(){
        running = false;
    }

    public void run(){
        try{
            init();
            gameLoop();
        }finally{
            s.restoreScreen();
        }
    }

    public void init(){
        s = new ScreenManager();
        DisplayMode dm = s.findFirstCompatibleMode(modes);
        s.setFullScreen(dm);


        Window w = s.getFullScreenWindow();
        w.setFont(new Font("Arial", Font.PLAIN, 20));
        w.setBackground(Color.black);
        w.setForeground(Color.white);
    }

    public void gameLoop(){
        long startTime = System.currentTimeMillis();
        long cumTime = startTime;

        while (running)
        {
            long timePassed = System.currentTimeMillis() - cumTime;
            cumTime += timePassed;
            if (limitfps){
            try{
                Thread.sleep(15);
            }catch(Exception e){}
            }
            update(timePassed);
            Graphics2D g = s.getGraphics();
            draw(g);
            g.dispose();
            s.update();
        }
    }

    public void update(long timePassed){
    }

    public boolean limitfps = false;

        public void draw(Graphics2D g){
        g.clearRect(0, 0, s.getWidth(), s.getHeight());
        AlphaComposite ac = java.awt.AlphaComposite.getInstance(AlphaComposite.CLEAR,0.5F);
        g.setComposite(ac);
        g.drawImage(new ImageIcon("Images/Test.png").getImage(), 30, 30, 30, 30, null);
        }







}

如果您运行此操作,则必须使用alt + tab并结束该过程(因为它在此部分代码中没有任何内容可以执行此操作)

1 个答案:

答案 0 :(得分:21)

您使用了错误的规则 - 请勿使用AlphaComposite.CLEAR。

AlphaComposite API说明了CLEAR:

  

目的地的颜色和阿尔法都被清除(Porter-Duff清除规则)。源和目的地都不用作输入。

这样会使图像消失。试验其他规则。当你创建你的SSCCE时,我创建了我的。看看当你为另一个注释掉一个规则行时会发生什么。例如,改变这个

// int rule = AlphaComposite.CLEAR;
int rule = AlphaComposite.SRC_OVER;

到此:

int rule = AlphaComposite.CLEAR;
// int rule = AlphaComposite.SRC_OVER;

整个SSCCE:

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.image.BufferedImage;

import javax.swing.*;

public class TestAlphaComposite extends JPanel {
   private static final int PREF_W = 400;
   private static final int PREF_H = PREF_W;
   private static final Stroke BASIC_STROKE = new BasicStroke(6f);
   BufferedImage backgroundImage;
   BufferedImage overlayImage;

   public TestAlphaComposite() {
      backgroundImage = createBackGroundImage();
      overlayImage = createOverlayImage();
   }

   private BufferedImage createBackGroundImage() {
      BufferedImage img = new BufferedImage(PREF_W, PREF_H,
            BufferedImage.TYPE_INT_ARGB);
      Graphics2D g2 = img.createGraphics();
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setStroke(BASIC_STROKE);
      g2.setColor(Color.blue);
      int circleCount = 10;
      for (int i = 0; i < circleCount ; i++) {
         int x = (i * PREF_W) / (2 * circleCount);
         int y = x;
         int w = PREF_W - 2 * x;
         int h = w;
         g2.drawOval(x, y, w, h);
      }
      g2.dispose();
      return img;
   }

   private BufferedImage createOverlayImage() {
      BufferedImage img = new BufferedImage(PREF_W, PREF_H,
            BufferedImage.TYPE_INT_ARGB);
      Graphics2D g2 = img.createGraphics();
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setStroke(BASIC_STROKE);
      g2.setColor(Color.red);
      int circleCount = 10;
      for (int i = 0; i < circleCount + 1; i++) {
         int x1 = (i * PREF_W) / (circleCount);
         int y1 = 0;
         int x2 = PREF_W - x1;
         int y2 = PREF_H;
         float alpha = (float)i / circleCount;
         if (alpha > 1f) {
            alpha = 1f;
         }
         // int rule = AlphaComposite.CLEAR;
         int rule = AlphaComposite.SRC_OVER;
         Composite comp = AlphaComposite.getInstance(rule , alpha );
         g2.setComposite(comp );
         g2.drawLine(x1, y1, x2, y2);
      }
      g2.dispose();
      return img;
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      if (backgroundImage != null) {
         g.drawImage(backgroundImage, 0, 0, null);
      }
      if (overlayImage != null) {
         g.drawImage(overlayImage, 0, 0, null);
      }
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("TestAlphaComposite");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new TestAlphaComposite());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

顺便说一下,你的SSCCE并不是真正的SSCCE。我们任何人都无法编译或运行该代码,因为它具有我们无法访问的依赖关系,即&#34; com.blazingkin.atrox.ScreenManager&#34;。如果您将来需要我们的帮助,您将要写出更好的符合sscce的要求。