Title: Composition
Course: CPS 261: Advanced Java Concepts ~ DL & MM MASTER

Composition

Composition deals with what does the user see when 2 Shapes or Images overlap. When we include Transparency parameters, the options can be quite large. The java.awt.AlphaComposite is constructed to define the rules for what the user sees.

If you want to see the mathematical details on how this works you can look at the Java API documentation for java.awt.AlphaComposite. However a picture is worth a thousand words, so I created the following application which shows you all of the rules on the left hand side, and the Transparency Alpha parameter along the top.

The constructor for AlphaComposite is as follows:

AlphaComposite composite= new AlphaComposite(int rule, float alpha);

In general, you would do something like:

Graphics2D g2d = .....

AlphaComposite composite = new AlphaComposite(SRC_OVER, 0.5f);

g2d.setComposite(composite);

..... Draw the next object.

However to get the drawing you see below to show all of the possibilities at once I had to create temporary BufferedImages of each option and then draw them onto the real screen.

So you will see a blue filled rectange overlapped with a slightly shifted green rectangle.

Note that SRC_OVER and SRC_ATOP and SRC are some of the main options we will want to use. The others are there for completeness.

CompositionRules.java


import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;



public class CompositeRules extends JFrame{

    private  int rules[] = {

            AlphaComposite.CLEAR,
            AlphaComposite.SRC,
            AlphaComposite.DST,
            AlphaComposite.SRC_OVER,
            AlphaComposite.DST_OVER,
            AlphaComposite.SRC_IN,
            AlphaComposite.DST_IN,
            AlphaComposite.SRC_OUT,
            AlphaComposite.DST_OUT,
            AlphaComposite.SRC_ATOP,
            AlphaComposite.DST_ATOP,
            AlphaComposite.XOR
    };
    private String ruleName[]={
            "CLEAR", "SRC", "DST", "SRC_OVER", "DST_OVER", "SRC_IN",
            "DST_IN", "SRC_OUT","DST_OUT","SRC_ATOP", "DST_ATOP","XOR"};

    CompositeRules()
    {
        setSize(500, 820);
        setTitle("CompositeRules");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
    public void paint(Graphics g)
    {
        Graphics2D g2d = (Graphics2D) g.create();
        Composite originalComposite = g2d.getComposite();
        int xlabel=90;
        for (float alpha=1; alpha >= 0; alpha -= 0.2f)
        {
            String s = String.format("%.1f",alpha);
            g2d.drawString(s, xlabel, 40);
            xlabel+=60;
        }

        for (int x = 20, y = 60, i = 0; i < rules.length; y += 60, i++)
        {

            BufferedImage buffImg = new BufferedImage(600, 60,
                    BufferedImage.TYPE_INT_ARGB);
            Graphics2D gbi = buffImg.createGraphics();
            int xrec=0;

            for (float alpha=1; alpha >= 0; alpha -= 0.2f)
            {
                gbi.setComposite(originalComposite);
                gbi.setPaint(Color.blue);
                gbi.fillRect(xrec, 0, 40, 40);

                AlphaComposite ac = AlphaComposite.getInstance(rules[i], alpha);
                gbi.setComposite(ac);

                gbi.setPaint(Color.green);
                gbi.fillRect(xrec+10, 10, 40, 40);
                xrec+= 60;
            }
            g2d.drawImage(buffImg, x+60, y, null);
            g2d.drawString(ruleName[i], 10, y+20);
            gbi.dispose();

        }

        g2d.dispose();
    }

    public static void main(String[] args)
    {
        CompositeRules cr = new CompositeRules();
    }

}






Sun Fadeout against clouds

The following is a simple but very useful scenario using these concepts. We have 2 images with the clouds in the background. The sun is drawn with a SRC_OVER rule, but we have the Transparency alpha slowly decreasing to create a Sun fading out scene.

Alpha decreasing ---------->

You will need:

cloud.png

sun.png

FadeOut.java


import java.awt.AlphaComposite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.Timer;



public class FadeOut extends JFrame implements ActionListener{

    private BufferedImage imageSun, imageCloud;
    private float alpha = 1f;
    Timer timer;

    FadeOut()
    {
        loadImages();
        setSize(400, 200);
        setTitle("FadeOut");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

        timer = new Timer(80, this);
        timer.setInitialDelay(500);
        timer.start();
    }
    private void loadImages() {
        try {

            imageSun = ImageIO.read(new File("sun.png"));
            imageCloud = ImageIO.read(new File("cloud.png"));

        } catch (IOException ex) {

            System.out.println("Error reading in images: +ex");
        }
    }
    public void paint(Graphics g)
    {
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.drawImage(imageCloud, 20, 20, null);

        AlphaComposite acomp = AlphaComposite.getInstance(
                AlphaComposite.SRC_OVER, alpha);
        g2d.setComposite(acomp);
        g2d.drawImage(imageSun, 50, 50, null);
        System.out.printf("paint, alpha=%.2f%n",alpha);

        g2d.dispose();

    }
    @Override
    public void actionPerformed(ActionEvent e) {
        alpha += -0.01f;

        if (alpha <= 0)
        {
            alpha = 0;
            timer.stop();
        }
        repaint();
    }

    public static void main(String[] args)
    {
        FadeOut fo = new FadeOut();
    }


}


Last Updated: June 18, 2015 4:30 PM