Drawing a transparent image

I’m trying to make a certain colour of a picture transparent by looping through every pixel and if its value is equal to the color to be replaced, I replace it with another value that I think is transparent. However, when I draw the image with my g2d instance it doesn’t come out transparent. The color is changed from the original colour to something else. I’m guessing that I either have the wrong RGB value for the alpha, or that I have to do something with the g2d instance in order to make it draw transparent colors? If that is the case, what should I do?

The RGB values I have tried are 0x00000000, 0 and 0x8F1C1C.

Help please!!

Thanks!

edit: I’ve checked google and used the search function, but they have not taught me anything new.

If your picture has no transparent, the image type may not be a transparent type.
First copy your image to INT_RGBA image (for exemple). Then replace your color to 0

Really quickly done dirty code :


  BufferedImage setTransparent(Image img,int color) // Don't forget to put the alpha value FF in the color
  {
     BufferedImage result = new BuffereImage(img.getWidth(),img.getHeight,BufferedImage.INT_RGBA);
     Graphics g = result.getGraphics();
     g.draw(img,0,0,null);
     g.dispose();
  
     for(int i=0;i<result .getWidth();i++)
     {
         for(int j=0;j<result .getHeight();j++)
        {
           int v = result.getRGB(i,j);

          if(v == color) {  result .setRGB(i,j,0); }
        }
     }

     return result;
  }

You cannot set alpha values using bufimg.setRGB()

Use bufimg.getAlphaRaster() to write the alpha values.

this is my code to search a color with and replace it with a specified ARGB value.


   public static BufferedImage replaceColor(BufferedImage srcBuf, int cSearch, int cReplace)
   {
      int[] srcRGB = srcBuf.getRGB(0, 0, srcBuf.getWidth(), srcBuf.getHeight(), null, 0, srcBuf.getWidth());

      int[] dstRGB = new int[srcRGB.length];
      int[] dstA = new int[dstRGB.length];

      for (int i = 0; i < srcRGB.length; i++)
      {
         if ((srcRGB[i] & 0x00FFFFFF) == cSearch) // match RGB
         {
            dstRGB[i] = cReplace & 0x00FFFFFF; // set RGB
            dstA[i] = (cReplace >> 24) & 0xFF; // set A
         }
         else
         {
            dstRGB[i] = srcRGB[i]; // copy RGB
            dstA[i] = 0xFF; // make A opaque
         }
      }

      BufferedImage dstBuf = new BufferedImage(srcBuf.getWidth(), srcBuf.getHeight(), BufferedImage.TYPE_INT_ARGB);
      dstBuf.setRGB(0, 0, dstBuf.getWidth(), dstBuf.getHeight(), dstRGB, 0, dstBuf.getWidth());
      dstBuf.getAlphaRaster().setPixels(0, 0, dstBuf.getWidth(), dstBuf.getHeight(), dstA);

      return dstBuf;
   }

I’m just using transparent png files instead of doing this…
is there much less memory usage doing it like that or any other advantages ?

The runtime memory consumption will be same, afterall an RGBA image is an RGBA image, no matter how it was loaded/generated. Disk space requirements are obviously smaller if you use RGB images, but unless you’re doing applets or something else where disk space counts it’s completely fine to use RGBA images like .pngs. :slight_smile:

Thanks, but I still can’t get this to work. I stole the code posted by Riven, and I’m calling it like this:

spriteImage = Cam.replaceColor(spriteImage, spriteImage.getRGB(0,spriteImage.getHeight()-1), Color.YELLOW.getRGB());

And I’ve made sure that spriteImage is of the type TYPE_INT_ARGB. I know it’s not supposed to be yellow, but no colors work. What am I doing wrong here? Thanks!

You are supposed to pass a ARGB value in the last parameter.

replaceColor(img, RGB, ARGB)

To replace red with opaque yellow:


BufferedImage sprite = ...;
sprite = replaceColor(sprite, 0xFF000, 0xFFFFFF00);

To replace purple with fully transparant white:


BufferedImage sprite = ...;
sprite = replaceColor(sprite, 0xFF00FF 0x00FFFFFF);

I did this specifically for a sprite sheet loader I put into the level editor of a game. That was because it would accept sprite sheets from the internet, which could be fairly random in terms of whether they had transparency or not.

Okay, but how do I get the ARGB value of a certain color?

Cheers

Sorry, I was wrong, color.getRGB() does return the ARGB value!

So passing Color.YELLOW should work.

Remember that images which start out life as JPGs don’t have exact values for colors. Jpeg
encode/decode changes color values, and changes solid color areas into salt-n-pepper of
similar values.

In that case what am I doing wrong?

Do I need to utilize a certain composite for this? And the image has been a .png all the time.

No need to do any fancy stuff.

Just make your test case simpler.

Create an image that’s fully red.
Load from disk, replace red to yellow, write to disk.
View the image in your favourite app, and see if it works.