Coloring a gray image

hi people!

i’ve some problems. Having a grayscale image, i want to change it in a colored image. For example, if red is chosen as basic color, then what’s dark gray would be dark red, light gray would become light red…
Any idea how to do this?

Secondly, i heard BufferedImage is not hardware accelerated. Therefore, is there a way to store the newly created image in an accelerated format? (This question is less important)

thanks in advance

Any idea how to do this?

I did something like that this way:
http://www.java-gaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=2D;action=display;num=1074430444;start=8#8

But read trembovetski’s post first (end of the page)

Secondly, i heard BufferedImage is not hardware accelerated.

Hmnaah you can’t say it this way. With 1.4 you need to copy it over once in order to get a managed (accelerated) image.


GraphicsConfiguration gc;
GraphicsDevice device;
[...]
device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
gc = device.getDefaultConfiguration();
[...]
//later:
BufferedImage ew = gc.createCompatibleImage(168,108,Transparency.OPAQUE);
Graphics2D tg = (Graphics2D)ew.getGraphics();
tg.setComposite(AlphaComposite.Src);
tg.drawImage(ewImg,0,0,null);
tg.dispose();

With 1.5 they should be managed by default :slight_smile:

…interesting, thanks.
but it seems already complicated. :stuck_out_tongue: Wouldn’t it be easier to work directly with the BufferedImage and getRGB/setRGB?

I always have the feeling dealing with 2D images is complicated.

I also have a very annoying problem where you’ve surely a quick answer. When i create an image using the Toolkit or IconImage, all i get is a not loaded image with -1 as width and height. I also tried to add a MediaTracker with
tracker.addImage(img, 0);
tracker.waitForID(0);
but the result is the same. So what should i do to have a damn loaded image?!
(brrr… this annoys me)

And you, don’t you find it could be made much more easier?

Uuuuh mediatracker ;D

ImageIO is nicer.


import javax.imageio.ImageIO;
[...]
BufferedImage img = javax.imageio.ImageIO.read(getClass().getResource("/gfx/set.gif"));

This kind of images (from imageio) will be managed by default with 1.5. With 1.4 you have to copy em once (as seen before).

If you are writing an (J)Applet or a non signed webstart application do this at the very beginning:


ImageIO.setUseCache(false);

(caching needs writing permissions doh)

I always have the feeling dealing with 2D images is complicated.

Basic stuff is pretty easy once you’ve figured it out (btw the way I did that multi color versions is the hard way to do it).

Well, ImageIO is pretty neat. The ‘o’ there is “out”, you can also write files with it.


import java.awt.*;
import java.awt.Image;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.*;

public class C4096
{
      public static void main(String[] args)
      {
            BufferedImage outImage = new BufferedImage(16,256,BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = outImage.createGraphics();

            int x=0;
            int y=0;
            int c=0;
            for(int r=0;r<16;r++)
            {
                  for(int g=0;g<16;g++)
                  {
                        for(int b=0;b<16;b++)
                        {
                              //g2d.setColor(new Color(r*16,g*16,b*16));
                              g2d.setColor(new Color(g*17,r*17,b*17));
                              g2d.fillRect(x,y,x+1,y+1);
                              c++;
                              x++;
                              //if(x==64)
                              if(x==16)
                              {
                                    x=0;
                                    y++;
                              }
                              System.out.println(r+"/"+g+"/"+b);
                        }
                  }
            }
            System.out.println("colors:"+c);

            g2d.dispose();

            try
            {
                  ImageIO.write(outImage, "png", new File("4096.png"));
            }
            catch (IOException e)
            {
                  e.printStackTrace();
            }
      }
}

That for example creates a nice little image with all 4096 colors you have in 12bit mode. It looks like this (but rotated by 90°)

The reason for changing the the setColor method parameters was giving a better contrast variation across the image. Green appears to be the brightest color, therefore it gets one bit more in 16bit (5-6-5) and for that reason I decided to spread the green part across the whole image :slight_smile:

thanks, i’ll try it!

This may be silly, but I’ll throw it out there anyway. If it’s just a one-time coloring of some image (as opposed to needing to do it in the JRE), you can just do that with Photoshop. Very easy.

Hehe :slight_smile:

Well, usually you do this kind of stuff if you need several versions. Eg the same bunch of sprites in different colors. Sure you could do this with different colored images, but it would be slower and more important it would be a waste of space.

I did that at pixel level, because it was at that time the most intuitive way to do it (for me heh). Now I would do it a bit different - at raster level.

-create an new image
-paint it completely in that one color
-put the grayscale image into the alpha raster
-draw this thing it ontop of a completly black image (SrcOver)

et voila you have a recolored image.

With 2 grayscale images and one color you could create an image with a specific color and a full alpha chanel. A third grayscale image could be used for phong effects :wink:

For one of my sprites I use currently 4 grayscale images: Alpha mask (antialiased siluette), shadowing, spectacular (phong) and shadow. All of those are in a single 97x44 grayscale png.

Oh and be sure to use real grayscale and not an indexed image with grayscale palette entries - the palette is just overhead.