Рисование прозрачных изображений в Java Graphics2D

Я хочу нарисовать ЧАСТИЧНО прозрачное изображение поверх другого (создание теней над вещами). В настоящее время я использую класс java Graphics2D для рендеринга, мне сказали установить композит на AlphaComposite, но это только делает его полностью прозрачным.

Могу ли я сделать это с моими текущими настройками? Что мне нужно сделать, чтобы исправить это?

Мне сказали, что это код, который сделает его частично прозрачным:

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

(Кстати, я использую png-изображения)

Вот ваш sscce (все они в разных классах, но я собрал их вместе для простоты) (я использую изображение под названием «Тест» в локальной папке «Изображения», вы можете использовать для этого все, что угодно, если это изображение 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 и завершить процесс (поскольку в этой части кода нет ничего для этого)


person blazingkin    schedule 25.11.2011    source источник
comment
Вы заявляете "I've been told to set the composite to AlphaComposite, but that only sets it completely transparent...." ерунду. Альфа-композиция, если она установлена ​​правильно, может привести к полной градации прозрачности. Итак, вы, должно быть, делаете что-то не так, но мы не можем сказать, что без кода. Покажите нам код, желательно sscce.   -  person Hovercraft Full Of Eels    schedule 25.11.2011
comment
Там я разместил некоторый код, который, как мне кажется, должен устанавливать все, что я визуализирую, с частично прозрачным методом рисования.   -  person blazingkin    schedule 25.11.2011
comment
Я не могу проверить ваш код, так как не могу его запустить. Если вы не получите ответ в ближайшее время, рассмотрите возможность создания и публикации sscce (прочитайте ссылку, чтобы узнать, что это влечет за собой ).   -  person Hovercraft Full Of Eels    schedule 25.11.2011
comment
хорошо, я добавил sscce, который скомпилирует и покажет, что не так   -  person blazingkin    schedule 25.11.2011


Ответы (1)


Вы используете неправильное правило — не используйте 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.

person Hovercraft Full Of Eels    schedule 25.11.2011
comment
+1 за информативное sscce. См. также эту утилиту. - person trashgod; 25.11.2011
comment
Попробуйте то, что нашел @thrashgod, это маленькое приложение, которое само все объясняет! Спасибо thrashgod! - person Benj; 21.10.2013