Friday, April 1, 2011

Moving Objects and Sprite Manager - Part 4

This is part 4 of the series. It is suggested to read the whole series from the beginning.

Image Transparency

Let's recall the output in the previous article.


The bunny is surrounded by a non-transparent pink color. We have two approaches to make it transparent. The first approach is to draw the sprite image pixel by pixel and skip the transparent pixel as needed. This would be very inefficient and therefore we are taking the second approach. We would preprocess the image to update the transparent flag of each pixel.

Recall that Java provides an ARGB image model. It consists of 4 bytes packed into a 32 bit integer. RGB is the component color. And "A" stands for alpha which is the degree of transparency of a pixel. If "A" is zero, then it is completely transparent. If "A" is 0xff, then it is completely opaque. Since ARGB is packed into a integer,
color &= 0x00ffffff;
will effectively clear the alpha flag without affecting the RGB components.

A modification of the previous demonstration is listed below. You need to download "background.jpg" and "bunny_sprite.png" in the previous article to run the demo.

/******************************************************************************
* File : TransparentImage.java
* Author : http://java.macteki.com/
* Description :
*   Simple panel to demonstrate loading and drawing image with transparent color
* Tested with : JDK 1.6
******************************************************************************/


import java.awt.image.BufferedImage;

class TransparentImage extends javax.swing.JPanel
{
  BufferedImage backgroundImage;
  BufferedImage spriteImage;

  public TransparentImage() throws Exception
  {
    // load background image
    backgroundImage=javax.imageio.ImageIO.read(new java.io.File("background.jpg"));

    // load sprite image, preprocess transparent color
    BufferedImage tmp=javax.imageio.ImageIO.read(new java.io.File("bunny_sprite.png"));
    spriteImage = makeTransparent(tmp);


    // set the panel size to the dimension of the background image
    int panelWidth=backgroundImage.getWidth(null);
    int panelHeight=backgroundImage.getHeight(null);
    setPreferredSize(new java.awt.Dimension(panelWidth,panelHeight));
  }


  private BufferedImage makeTransparent(BufferedImage tmpImage)
  {
    int h=tmpImage.getHeight(null);
    int w=tmpImage.getWidth(null);

    BufferedImage resultImage=new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);

    // assume the upperleft corner of the original image is a transparent pixel
    int transparentColor=tmpImage.getRGB(0,0);  
    for (int y=0;y<h;y++)
      for (int x=0;x<w;x++)
      {
        int color=tmpImage.getRGB(x,y);
        if (color==transparentColor) color=color & 0x00FFFFFF; // clear the alpha flag
        resultImage.setRGB(x,y,color);
      }

    return resultImage;
  }

  // override the paint() method
  public void paintComponent(java.awt.Graphics gr)
  {
    gr.drawImage(backgroundImage,0,0,this);

    gr.drawImage(spriteImage,50,200,this);
  }

  public static void main(String[] args) throws Exception
  {
    javax.swing.JFrame window = new javax.swing.JFrame();
    window.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
    window.setTitle("Macteki Image Panel");

    TransparentImage imagePanel=new TransparentImage();
    window.add(imagePanel);

    window.pack();
    window.setVisible(true);
  
  }
}


The result is as expected



Going next

We are going to have the bunny running in the next article.

Part 4 completed. To be continued...

Acknowledgement

  1. bunny_sprite.png is provided by Moosader :
    http://moosader.deviantart.com/art/Public-domain-bunny-sprite-151156167

  2. background.jpg is provided by Jesccia Crabtree
    http://www.jessicacrabtree.com/journal1/public-domain-nature-photos

No comments:

Post a Comment