| As discussed in Chapter 
              6: Java : Colors the default ARGB color model in Java uses red, 
              green, and blue components plus an alpha transparency factor (discussed 
              below.) A color can be obtained as a Color 
              object. However, with images you usually deal with an array of pixels 
              in which each pixel is a 32-bit int 
              value with the four components packed each as an 8-bit value. Chapter 
              10: Tech : Bits shows how to access and modify the four color 
              components in a int 
              value.  The RGB model implies a monitor pixel. RGB is an 
              additive color model (e.g. equal parts of red, green, and blue combine 
              to display gray up to white depending on the intensities) . However, 
              when an image is sent to a printer, 
              the image dots in that case will be translated for you into the 
              pigment color combinations that provide similar, if not an exact, 
              reproduction of the monitor colors. In the Pixel Handling 
              section, we show how to access and modify the pixels of an image. Transparency The fourth component of the color model used above 
              is the alpha or transparency component.  alpha 
              - 8 bits in top byte of the 32 bit pixel value. This is used when an image is overlaid above a background 
              color or another image. The transparency determines how the background 
              color combines with the foreground color in the resulting combined 
              pixel value. This can be useful for various image manipulation 
              such as when overlaying an icon on a component. Typically you want 
              the blank areas of the icon to show the background component. The program TransparencyApplet 
              below demonstrates the effect of the alpha transparency factor in 
              pixel values. The user selects a color for a large rectangle and 
              also selects both the color and transparency of a smaller rectangle 
              drawn over the larger one. The drawing is done first on an off-screen 
              image and then the image is drawn on a JPanel. 
             If the small rectangle color is opaque, i.e. the alpha 
              component equals 255, then only its RGB color will be display. Or, 
              if the alpha equals 0, then only the big rectangle color will be 
              seen. However, things get more interesting when you set alpha to 
              an intermediate value.  From the image we can obtain the pixels that result 
              from combining the two colors with an intermediate alpha setting. 
              We display the pixel value on the applet .(To access the pixesl 
              we use the PixelGrabber 
              class that is discussed in the Pixel 
              Handling section.)
  
              
                 
                  | TransparencyApplet + BgControlPanel 
                    + FgControlPanel 
                    + OutputPanel
 |   
                  |  import 
                      javax.swing.*;import java.awt.*;
 import java.awt.event.*;
 
 /**
 * Demonstrate effect of the alpha transparency 
                      factor in pixel
 * values. The user selects via the BgControlPanel 
                      a color for a
 * large rectangle. Similarly, the user selects 
                      via the FgControlPanel
 * both the color and transparency factor of 
                      a small rectangle painted
 * over the larger one. The rectangles are displayed 
                      on the OutputPanel.
 * The resulting pixel value in the overlay area 
                      is displayed on
 * the output
 **/
 public class TransparencyApplet extends JApplet
 {
 /** Create the user interface with OutputPanel 
                      and two control panels.**/
 public void init () {
 
 setLayout (new GridLayout (2,1));
 
 // Create an instance of OutputPanel
 OutputPanel output_panel = new OutputPanel 
                      ();
 
 // Create an instance of the background 
                      color control panel
 BgControlPanel bg_control_panel 
                      = new BgControlPanel (output_panel);
 
 // Create an instance of the foreground 
                      color control panel
 FgControlPanel fg_control_panel 
                      = new FgControlPanel (output_panel);
 
 JPanel controls_panel = new JPanel 
                      (new GridLayout (1,2));
 
 controls_panel.add(bg_control_panel);
 controls_panel.add(fg_control_panel);
 
 // Add the panels to applet's pane.
 add (output_panel);
 add (controls_panel);
 } // init
 
 } // class TransparencyApplet
 
 |   
                  | import 
                      javax.swing.*;import java.awt.*;
 import java.awt.image.*;
 
 /**
 * This JPanel subclass displays one large rectangle
 * with a background color plus a smaller rectangle
 * drawn over the first one with a foreground 
                      color. The
 * background and foreground colors can be set 
                      with the
 * setBgColor and setFgColor methods respectively.
 *
 * The drawing is first done on an offscreen 
                      image so that
 * we can obtain the pixel that results from 
                      the combination
 * of the two colors. The alpha factor selected 
                      for the
 * foreground will affect the combination color.
 **/
 public class OutputPanel extends JPanel {
 Color fBgColor = Color.RED;
 Color fFgColor = Color.BLUE;
 
 /**
 * Set the background color by passing 
                      the 3 RGB component
 * values  (with ranges 
                      0-255).
 **/
 void setBgColor (int cr, int cg, int cb) {
 fBgColor = new Color (cr,cg,cb);
 repaint ();
 }
 
 /**
 * Set the color of the foreground 
                      overlpay
 * by passing the 3 RGB component 
                      values
 * plus the alpha value (with ranges 
                      0-255).
 **/
 void setFgColor (int cr, int cg, int cb, int 
                      ca) {
 fFgColor = new Color (cr,cg,cb,ca);
 repaint ();
 }
 
 /**
 * Use an offscreen image to draw 
                      a rectangle with the
 * background color and then overlay 
                      a smaller rectangle
 * with the foreground color amd  alpha 
                      factor selected
 * by the user. This image is then 
                      drawn on the panel.
 *
 * To find out the pixel value that 
                      results from this
 * combination of the background 
                      color plus the overlay color,
 * we use a PixelGrabber object to 
                      get the pixel array.
 * The resulting pixel value is drawn 
                      on the center of the panel.
 **/
 public void paintComponent (Graphics g) {
 super.paintComponent (g);
 
 int panelWd = getWidth ();
 int panelHt = getHeight ();
 
 Image img = createImage (panelWd,panelHt);
 Graphics img_gc = img.getGraphics 
                      ();
 
 // Now we fill a rectangle the size 
                      of the
 // panel with the chosen color.
 img_gc.setColor (fBgColor);
 img_gc.fillRect (0, 0, panelWd, 
                      panelHt);
 
 // Now overlay a rectanagular patch 
                      over the panel
 // and fill it with the foreground 
                      color.
 int x = (int)(0.20 * panelWd);
 int y = (int)(0.20 * panelHt);
 
 int patchWd = (int)(0.60 * panelWd);
 int patchHt = (int)(0.60 * panelHt);
 
 img_gc.setColor (fFgColor);
 img_gc.fillRect (x, y, patchWd, 
                      patchHt);
 
 g.drawImage (img, 0, 0, this);
 
 // To determine the color of the 
                      combination of background
 // and foreground overlay, we grab 
                      the pixels from the overlay
 // region of the offscreen image.
 int [] pixels = new int[patchWd 
                      * patchHt];
 PixelGrabber pg =
 new PixelGrabber (img, x, 
                      y, patchWd, patchHt, pixels, 0, patchWd);
 
 // The grabPixels method will cause 
                      the filling of the
 // pixels array.
 try {
 pg.grabPixels ();
 }
 catch (InterruptedException e) {
 System.err.println 
                      ("Interrupted while waiting for pixels!");
 return;
 }
 // Pixel filling isn't instantaneous 
                      so check here to
 // see that it finished.
 if ((pg.getStatus () & ImageObserver.ABORT) 
                      != 0) {
 System.err.println 
                      ("Image fetch abort or error occurred");
 return;
 }
 
 // Look at one of the pixels (they 
                      should all have the identical
 // value except perhaps at the edge.
 int color_value = pixels[pixels.length 
                      / 2];
 
 // Get the value in hex format and 
                      draw it at the center
 //  
                      of the panel.
 String color_value_str = Integer.toHexString 
                      (color_value);
 g.setColor(Color.BLACK);
 drawStringInCenter(g, color_value_str);
 
 } // paintComponent
 
 /** Use FontMetrics classes to draw a string 
                      at
 * the center of a panel.
 **/
 void drawStringInCenter(Graphics g, String msg) 
                      {
 
 // Create the font and pass it to 
                      the  Graphics context
 g.setFont (new Font ("Monospaced",Font.BOLD,18));
 
 // Get measures needed to center 
                      the message
 FontMetrics fm = g.getFontMetrics 
                      ();
 
 // How many pixels wide is the string
 int msg_width = fm.stringWidth (msg);
 
 // How far above the baseline can 
                      the font go?
 int ascent = fm.getMaxAscent ();
 
 // How far below the baseline?
 int descent= fm.getMaxDescent ();
 
 // Use the string width to find 
                      the starting point
 int msg_x = getSize ().width/2 - 
                      msg_width/2;
 
 // Use the vertical height of this 
                      font to find
 // the vertical starting coordinate
 int msg_y = getSize ().height/2 
                      - descent/2 + ascent/2;
 
 g.drawString (msg, msg_x, msg_y);
 
 } // drawStringInCenter
 
 } // class OutputPanel
 
 |   
                  | import java.awt.*; import java.awt.event.*;
 import javax.swing.*;
 import javax.swing.event.*;
 
 /**
 * The FgControlPanel holds four JSlider widgets 
                    that set
 * the color and transparency of the foreground 
                    rectangle
 * patch drawn on the OutputPanel.
 **/
 public class FgControlPanel extends JPanel
 implements 
                    ChangeListener {
 
 OutputPanel fOutputPanel;
 JLabel fRedLabel,fGreenLabel,fBlueLabel,fAlphaLabel;
 JSlider fRed,fGreen,fBlue,fAlpha;
 
 FgControlPanel (OutputPanel output_panel) {
 
 fOutputPanel = output_panel;
 
 setLayout (new GridLayout (4, 2));
 
 add (fRedLabel = new JLabel ("Red 
                    0  ",SwingConstants.RIGHT) );
 
 // The JSlider constructor parameters:
 //
 //   orientation, minimum, 
                    maximum, inital value
 //
 // The sliders are set horizontally.
 // The values range from 0 to 255.
 // Set the blue slider to max initially 
                    to match the
 // initial blue color for the output 
                    panel overlay.
 //
 add (fRed = new JSlider (JSlider.HORIZONTAL, 
                    0, 255, 0));
 fRed.addChangeListener (this);
 
 add (fGreenLabel = new JLabel ("Green 
                    0  ",SwingConstants.RIGHT) );
 add (fGreen = new JSlider (Adjustable.HORIZONTAL, 
                    0, 255, 0));
 fGreen.addChangeListener (this);
 
 add (fBlueLabel = new JLabel ("Blue 
                    0  ",SwingConstants.RIGHT) );
 add (fBlue = new JSlider (Adjustable.HORIZONTAL, 
                    0, 255, 255));
 fBlue.addChangeListener (this);
 
 add (fAlphaLabel = new JLabel ("Alpha 
                    0  ",SwingConstants.RIGHT) );
 add (fAlpha = new JSlider (Adjustable.HORIZONTAL, 
                    0, 255, 255));
 fAlpha.addChangeListener (this);
 
 // Initialize to opaque blue.
 fOutputPanel.setFgColor(0,0,255,255);
 
 } // ctor
 
 /** This class is the AdjustmentListener for the
 * scroll bar. So the events come here 
                    when the
 * scroll bar is moved.
 **/
 public void stateChanged (ChangeEvent evt){
 
 // Use the labels to show the numerical 
                    values of the
 // scroll bar settings.
 fRedLabel.setText ("Red " +
 Integer.toHexString (fRed.getValue ()));
 fGreenLabel.setText ("Green " +
 Integer.toHexString (fGreen.getValue ()));
 fBlueLabel.setText ("Blue " +
 Integer.toHexString (fBlue.getValue ()));
 fAlphaLabel.setText ("Alpha "+
 Integer.toHexString 
                    (fAlpha.getValue ()));
 
 // Get the values from each scroll 
                    bar and pass
 // them as the color component values.
 fOutputPanel.setFgColor (fRed.getValue 
                    (), fGreen.getValue (),
 fBlue.getValue (),fAlpha.getValue ());
 
 fOutputPanel.repaint ();
 } // stateChanged
 
 } // class FgControlPanel
 
 |   
                  | import 
                    java.awt.*; import java.awt.event.*;
 import javax.swing.*;
 import javax.swing.event.*;
 
 /**
 * The FBControlPanel holds four JSlider widgets 
                    that set
 * the color of the large background rectangle 
                    drawn on
 * the OutputPanel.
 **/
 public class BgControlPanel extends JPanel
 implements 
                    ChangeListener {
 
 OutputPanel fOutputPanel;
 JLabel fRedLabel,fGreenLabel,fBlueLabel;
 JSlider fRed,fGreen,fBlue;
 
 BgControlPanel (OutputPanel output_panel) {
 
 fOutputPanel = output_panel;
 
 setLayout (new GridLayout (3, 2));
 
 add (fRedLabel = new JLabel ("Red 
                    0  ",SwingConstants.RIGHT) );
 
 // The JSlider constructor parameters:
 //
 //   orientation, minimum, 
                    maximum, inital value
 //
 // The sliders are set horizontally.
 // The values range from 0 to 255.
 // Set the red slider to max initially 
                    to match the
 // initial Red color for the output 
                    panel.
 //
 add (fRed = new JSlider (JSlider.HORIZONTAL, 
                    0, 255, 255));
 fRed.addChangeListener (this);
 
 add (fGreenLabel = new JLabel ("Green 
                    0  ",SwingConstants.RIGHT) );
 add (fGreen = new JSlider (Adjustable.HORIZONTAL, 
                    0, 255, 0));
 fGreen.addChangeListener (this);
 
 add (fBlueLabel = new JLabel ("Blue 
                    0  ",SwingConstants.RIGHT) );
 add (fBlue = new JSlider (Adjustable.HORIZONTAL, 
                    0, 255, 0));
 fBlue.addChangeListener (this);
 
 } // ctor
 
 /**
 * This class is the AdjustmentListener 
                    for the
 * scroll bar. So the events come here 
                    when the
 * scroll bar is moved.
 **/
 public void stateChanged (ChangeEvent evt) {
 
 // Use the labels to show the numerical 
                    values of the
 // scroll bar settings.
 fRedLabel.setText ("Red "+
 Integer.toHexString 
                    (fRed.getValue ()));
 fGreenLabel.setText ("Green " +
 Integer.toHexString (fGreen.getValue ()));
 fBlueLabel.setText ("Blue " +
 Integer.toHexString 
                    (fBlue.getValue ()));
 
 // Get the values from each scroll 
                    bar and pass
 // them as the color component values.
 fOutputPanel.setBgColor (fRed.getValue 
                    (), fGreen.getValue (),
 fBlue.getValue ());
 
 fOutputPanel.repaint ();
 
 } // stateChanged
 
 } // class BgControlPanel
 |    If you play with the color component values for the 
              background and the foreground areas and with the alpha value, you 
              will see that each of the RGB components are combined in a linear 
              manner. Lets define the transparency fraction as  
              frac = alpha/255 We also define an individual red, green, or blue component 
              for the background color as  
              Cbg and as Cfg 
              for the foreground color component. Then the color components are 
              combined as follows:  
              Ccombo 
                = (1 - frac) * Cbg + frac * Cfg This approach approximates the transparency effect that you would 
              see if you put a glass tinted with the foreground color in front 
              of a light with the background color.  References & Web Resources   Last update: Dec. 2, 2004 |