在Java Graphics2D中绘制透明图像 [英] Drawing Transparent Images In Java Graphics2D

查看:141
本文介绍了在Java Graphics2D中绘制透明图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to draw a PARTIALLY transparent image on top of another (Making shadows over things). I am currently using java's Graphics2D class to render, I've been told to set the composite to AlphaComposite, but that only sets it completely transparent.

我可以使用我目前的设置?我该怎么做才能解决这个问题?

Can I do this with my current setup? What do I have to do to fix this?

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

This is the code I was told that would make it partially transparent:

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

(我顺便使用png图像)

(I am using png images by the way)

继承你的sscce(这些都是在不同的类,但我把它们放在一起是为了简单)(我在本地文件夹Images中使用一个名为Test的图像,你可以使用任何东西,只要它是一个名为相同的图像

Heres your sscce (these are all in different classes but i put them together for simplicity) (I use an image called "Test" in the local folder "Images", you can use whatever for this as long as it is a png Image named the same

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 out并结束这个过程(因为它没有在这部分代码中做任何事情)

If you run this you will have to alt + tab out and end the process (as it doesnt have anything in this portion of code to do such)

推荐答案

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

You're using the wrong rule -- don't use AlphaComposite.CLEAR.

AlphaComposite API说明了CLEAR:

The AlphaComposite API states this about CLEAR:


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

Both the color and the alpha of the destination are cleared (Porter-Duff Clear rule). Neither the source nor the destination is used as input.

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

So this will make the image disappear. Experiment with other rules. While you were creating your SSCCE, I created mine. See what happens when you comment out the one rule line for the other. For example change this

// 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。我们任何人都无法编译或运行该代码,因为它具有我们无法访问的依赖项,即com.blazingkin.atrox.ScreenManager。如果你将来需要我们的帮助,你会想写更好的符合sscce的。

By the way, your SSCCE isn't a true SSCCE. There's no way that any of us can compile or run that code as it has dependencies that we don't have access to, namely "com.blazingkin.atrox.ScreenManager". If you need our help in the future, you'll want to write better complying sscce's.

这篇关于在Java Graphics2D中绘制透明图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆