Adding partial transparency to an image

Say we have an Image or BufferedImage loaded from a JPEG or GIF file. Basically the image consists of foreground chart and a plain background. The background is not important for that chart and we'd like to make the background transparent on our fancy(?) custom component.

What should be the steps of the process to get that kind of partially transparent Image or BufferedImage from original ones? I think I theoretically know that: get RGB array of the image -> convert it to RGBA array -> modify some of 'A' values -> reconstruct Java image from the RGBA array. However, for concrete steps using Java2D APIs, I am totally lost.

Thanks in advance.

[679 byte] By [hiwaa] at [2007-10-3 9:51:56]
# 1

I have found a solution. It is so simple that it is anticlimatic for me!

import javax.swing.*;

import javax.imageio.*;

import java.awt.*;

import java.awt.image.*;

import java.io.*;

public class Transparentize{

static final int th = 200; // whity threshold R/G/B value

// could be 240, 254, whatever

JFrame frame;

Container con;

RPanel rp;

BufferedImage scr, scrt;

int scrw; // image width

public Transparentize(){

frame = new JFrame();

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

con = frame.getContentPane();

try{

scr = ImageIO.read(new File("youngdad.jpg"));

}

catch (IOException e){

e.printStackTrace();

}

scrt = tp(scr); // get transparentized image

rp = new RPanel(scr.getWidth(), scr.getHeight());

con.add(rp, BorderLayout.CENTER);

frame.pack();

frame.setVisible(true);

}

/* get transparentized image */

BufferedImage tp(BufferedImage orig){

int w = orig.getWidth(null);

int h = orig.getHeight(null);

scrw = w;

int[] rgbs = new int[w * h];

orig.getRGB(0, 0, w, h, rgbs, 0, w);

for (int i = 0; i < rgbs.length; ++i){

int p = rgbs[i];

int r = (p >>> 16) & 0x000000ff;

int g = (p >>> 8) & 0x000000ff;

int b = p & 0x000000ff;

if (r > th && g > th && b > th){

p &= 0x00ffffff;

rgbs[i] = p;

}

}

// if you use 'orig' here, you fail in adding transparency to the image

// you should make a new BufferedImage with a proper image-type

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

bi.setRGB(0, 0, w, h, rgbs, 0, w);

return bi;

}

class RPanel extends JPanel{

public RPanel(int imgw, int imgh){

setPreferredSize(new Dimension(imgw * 2, imgh));

setBackground(new Color(255, 255, 150));

}

public void paintComponent(Graphics g){

Graphics2D g2 = (Graphics2D)g;

super.paintComponent(g);

g2.drawImage(scr, 0, 0, this); // original image

g2.drawImage(scrt, scrw, 0, this); // transparent image

}

}

public static void main(String[] args){

new Transparentize();

}

}

hiwaa at 2007-7-15 5:09:21 > top of Java-index,Security,Cryptography...
# 2

Another option:

import java.awt.*;

import java.awt.geom.*;

import java.awt.image.BufferedImage;

import javax.swing.*;

public class XPImage {

public static void main(String[] args) {

BufferedImage image = getImage();

JPanel panel = new JPanel();

panel.setBackground(Color.pink);

panel.add(new JLabel(new ImageIcon(image)));

JOptionPane.showMessageDialog(null, panel, "",

JOptionPane.PLAIN_MESSAGE);

}

private static BufferedImage getImage() {

int w = 100, h = 100, PAD = 10;

int type = BufferedImage.TYPE_INT_ARGB;

BufferedImage image = new BufferedImage(w, h, type);

Graphics2D g2 = image.createGraphics();

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

g2.setPaint(new Color(0,0,0,0));

g2.fillRect(0,0,w,h);

g2.setPaint(Color.black);

g2.draw(new Line2D.Double(10, h-PAD, w-PAD, h-PAD));

g2.draw(new Line2D.Double(w/2, PAD, w/2, h-PAD));

g2.setPaint(Color.blue);

g2.draw(new QuadCurve2D.Double(PAD,PAD,w/2,h*27/16,w-PAD,PAD));

g2.dispose();

return image;

}

}

crwooda at 2007-7-15 5:09:21 > top of Java-index,Security,Cryptography...
# 3
Thanks for the code, again.My current another problem is:if (aloc.colorIWantToTransparentized == anotherloc.colorIDontWantToTransparentized){ whatToDo(?);}
hiwaa at 2007-7-15 5:09:21 > top of Java-index,Security,Cryptography...
# 4

The three places in which you can select certain parts of the image to modify/avoid are:

orig.getRGB(0, 0, w, h, rgbs, 0, w);

for (int i = 0; i < rgbs.length; ++i){

...

bi.setRGB(0, 0, w, h, rgbs, 0, w);

The [x, y, width, height] rectangular section arguments allow you to specifically select the areas you can search and modify rgb values.

crwooda at 2007-7-15 5:09:21 > top of Java-index,Security,Cryptography...
# 5
Yeah! That's right! Thanks!And, good night from the Eastern Hemisphere of the globe.
hiwaa at 2007-7-15 5:09:21 > top of Java-index,Security,Cryptography...