web-dev-qa-db-ja.com

Java Graphics2Dで透明な画像を描画する

部分的に透明な画像を別の画像の上に描画したい(物に影を付ける)。現在、JavaのGraphics2Dクラスを使用してレンダリングしています。コンポジットをAlphaCompositeに設定するように言われましたが、完全に透明に設定されるだけです。

現在の設定でこれを行うことはできますか?これを修正するにはどうすればよいですか?

これは私がそれを部分的に透明にするだろうと言われたコードです:

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

(ちなみに私はpng画像を使用しています)

Heres your sscce(これらはすべて異なるクラスにありますが、簡単にするためにまとめました)(ローカルフォルダ「Images」で「Test」という画像を使用します。同じ

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 +タブアウトしてプロセスを終了する必要があります(そのためには、コードのこの部分に何もないため)。

20
blazingkin

間違ったルールを使用しています-AlphaComposite.CLEARを使用しないでください。

AlphaComposite APIは、CLEARについて次のように述べています。

宛先の色とアルファの両方がクリアされます(Porter-Duff Clearルール)。ソースと宛先のどちらも入力として使用されません。

これで画像が消えます。他のルールを試してください。あなたが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ではありません。アクセスできない依存関係、つまり「com.blazingkin.atrox.ScreenManager」があるため、そのコードをコンパイルまたは実行する方法はありません。将来私たちの助けが必要な場合は、より良い準拠のsscceを作成する必要があります。