javajava-2d

Java2D Compositing - Incorrect Java/Oracle Documentation


I am going to improve and supplement this question but maybe I'm right and someone knowing can help shortcut this question/issue... Isn't the following web documentation by Oracle incorrect? https://docs.oracle.com/javase/tutorial/2d/advanced/compositing.html

This seems to have been asked previously by the following post: Java Graphics Composite inconsistencies

I have some sample code and some screenshots that I will add in the next few days but, again, I feel the web documentation is either wrong or strongly misleading on the examples it gives. i.e. I cannot duplicate the examples AT ALL! At least not in the way they are described on the page. At best, I can somewhat duplicate the screenshots in the web page but have to swap "destination" and "source" and even then the applied composites do not match the web page. If I'm simply wrong and anyone has any insight that would help me understand the web page and java2d compositing as explained on that page, please let me know.

FWIW, I'll go ahead and add some preliminary information. Here is a screenshot of images created but they have swapped source and destination (as I am interpreting the tutorial). These images have the composites applied in the following order:

        AlphaComposite.SRC,
        AlphaComposite.DST,
        AlphaComposite.SRC_ATOP,
        AlphaComposite.DST_ATOP,
        AlphaComposite.SRC_IN,
        AlphaComposite.DST_IN,
        AlphaComposite.SRC_OUT,
        AlphaComposite.DST_OUT,
        AlphaComposite.SRC_OVER,
        AlphaComposite.DST_OVER,
        AlphaComposite.CLEAR

enter image description here

UPDATE: I have accepted Robby's answer and posted my own followup as an answer below. Now... how to get Oracle to clarify/correct their tutorial... :)


Solution

  • Alpha compositing works almost (see below) as described in the Oracle tutorial you referenced.

    Three points that might have led to the confusion:

    I have taken the 7 composition rules from the aforementioned tutorial (SRC_OVER, SRC_IN, SRC_OUT, DST_OVER, DST_IN, DST_OUT, and CLEAR), and used them in this example:

    import java.awt.AlphaComposite;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    class Panel extends JPanel {
        private final int[] rules = {
                AlphaComposite.SRC_OVER,
                AlphaComposite.SRC_IN,
                AlphaComposite.SRC_OUT,
                AlphaComposite.DST_OVER,
                AlphaComposite.DST_IN,
                AlphaComposite.DST_OUT,
                AlphaComposite.CLEAR,
        };
    
        private void composite(Graphics g) {
            Graphics2D g2d = (Graphics2D) g.create();
    
            BufferedImage dst = new BufferedImage(60, 60,
                    BufferedImage.TYPE_INT_ARGB);
            Graphics2D dstGraphics = dst.createGraphics();
            dstGraphics.setPaint(Color.black);
            dstGraphics.fillRect(0, 15, 40, 40);
            dstGraphics.dispose();
    
            BufferedImage src = new BufferedImage(60, 60,
                    BufferedImage.TYPE_INT_ARGB);
            Graphics2D srcGraphics = src.createGraphics();
            srcGraphics.setPaint(Color.orange);
            srcGraphics.fillOval(15, 0, 40, 40);
            srcGraphics.dispose();
    
            for (int x = 20, y = 20, i = 0; i < rules.length; x += 60, i++) {
                BufferedImage cmp = new BufferedImage(60, 60,
                        BufferedImage.TYPE_INT_ARGB);
                Graphics2D cmpGraphics = cmp.createGraphics();
                AlphaComposite ac = AlphaComposite.getInstance(rules[i], 1.0f);
                cmpGraphics.drawImage(dst, 0, 0, null);
                cmpGraphics.setComposite(ac);
                cmpGraphics.drawImage(src, 0, 0, null);
                cmpGraphics.dispose();
    
                g2d.drawImage(cmp, x, y, null);
            }
    
            g2d.dispose();
        }
    
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            composite(g);
        }
    }
    
    public class Compositing extends JFrame {
        public Compositing() {
            add(new Panel());
    
            setTitle("Compositing");
            setSize(460, 100);
            setLocationRelativeTo(null);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    
        public static void main(String[] args) {
            Compositing compositing = new Compositing();
            compositing.setVisible(true);
        }
    }
    

    This yields the following result, which is in line with the Oracle tutorial, except for the CLEAR rule: Compositing

    When substituting the XOR rule for the CLEAR rule, we get the expected result: Compositing with XOR