[ACCEPTED]-Change the alpha value of a BufferedImage?-bufferedimage

Accepted answer
Score: 13

@Neil Coffey: Thanks, I've been looking 7 for this too; however, Your code didn't 6 work very well for me (white background 5 became black).

I coded something like this 4 and it works perfectly:

public void setAlpha(byte alpha) {       
    alpha %= 0xff; 
    for (int cx=0;cx<obj_img.getWidth();cx++) {          
        for (int cy=0;cy<obj_img.getHeight();cy++) {
            int color = obj_img.getRGB(cx, cy);

            int mc = (alpha << 24) | 0x00ffffff;
            int newcolor = color & mc;
            obj_img.setRGB(cx, cy, newcolor);            



Where obj_img is 3 BufferedImage.TYPE_INT_ARGB.

I change alpha 2 with setAlpha((byte)125); alpha range is 1 now 0-255.

Hope someone finds this useful.

Score: 4

I don't believe there's a single simple 2 command to do this. A few options:

The first 1 is the simplest to implement, IMO.

Score: 4

This is an old question, so I'm not answering 37 for the sake of the OP, but for those like 36 me who find this question later.


As @Michael's 35 excellent outline mentioned, an AlphaComposite 34 operation can modify the alpha channel. But 33 only in certain ways, which to me are somewhat 32 difficult to understand:

enter image description here

is the formula for how the 31 "over" operation affects the alpha 30 channel. Moreover, this affects the RGB 29 channels too, so if you have color data 28 that needs to be unchanged, AlphaComposite 27 is not the answer.



There are several varieties 26 of BufferedImageOp (see 4.10.6 here). In the more general 25 case, the OP's task could be met by a LookupOp, which 24 requires building lookup arrays. To modify 23 only the alpha channel, supply an identity 22 array (an array where table[i] = i) for 21 the RGB channels, and a separate array for 20 the alpha channel. Populate the latter array 19 with table[i] = f(i), where f() is the function by which you 18 want to map from old alpha value to new. E.g. if 17 you want to "make every pixel in the 16 image that has a alpha value of 100 have 15 a alpha value of 80", set table[100] = 80. (The full 14 range is 0 to 255.) See how to increase opacity in gaussian blur for a code sample.


But 13 for a subset of these cases, there is a 12 simpler way to do it, that doesn't require 11 setting up a lookup table. If f() is a simple, linear 10 function, use a RescaleOp. For example, if you want 9 to set newAlpha = oldAlpha - 20, use a RescaleOp with a scaleFactor 8 of 1 and an offset of -20. If you want to 7 set newAlpha = oldAlpha * 0.8, use a scaleFactor of 0.8 and an offset 6 of 0. In either case, you again have to 5 provide dummy scaleFactors and offsets for 4 the RGB channels:

new RescaleOp({1.0f, 1.0f, 1.0f, /* alpha scaleFactor */ 0.8f},
              {0f, 0f, 0f, /* alpha offset */ -20f}, null)

Again see 4.10.6 here for some examples 3 that illustrate the principles well, but 2 are not specific to the alpha channel.

Both 1 RescaleOp and LookupOp allow modifying a BufferedImage in-place.

Score: 3

for a nicer looking alpha change effect, you 2 can use relative alpha change per pixel 1 (rather than static set, or clipping linear)

public static void modAlpha(BufferedImage modMe, double modAmount) {
    for (int x = 0; x < modMe.getWidth(); x++) {          
        for (int y = 0; y < modMe.getHeight(); y++) {
            int argb = modMe.getRGB(x, y); //always returns TYPE_INT_ARGB
            int alpha = (argb >> 24) & 0xff;  //isolate alpha

            alpha *= modAmount; //similar distortion to tape saturation (has scrunching effect, eliminates clipping)
            alpha &= 0xff;      //keeps alpha in 0-255 range

            argb &= 0x00ffffff; //remove old alpha info
            argb |= (alpha << 24);  //add new alpha info
            modMe.setRGB(x, y, argb);            
Score: 1

I'm 99% sure the methods that claim to deal 5 with an "RGB" value packed into an int actually 4 deal with ARGB. So you ought to be able 3 to do something like:

for (all x,y values of image) {
  int argb = img.getRGB(x, y);
  int oldAlpha = (argb >>> 24);
  if (oldAlpha == 100) {
    argb = (80 << 24) | (argb & 0xffffff);
    img.setRGB(x, y, argb);

For speed, you could 2 maybe use the methods to retrieve blocks 1 of pixel values.

Score: 0

You may need to first copy your BufferedImage 4 to an image of type BufferedImage.TYPE_INT_ARGB. If your image is 3 of type, say, BufferedImage.TYPE_INT_RGB, then the alpha component 2 won't be set correctly. If your BufferedImage 1 is of type BufferedImage.TYPE_INT_ARGB, then the code below works. /** * Modifies each pixel of the BufferedImage so that the selected component (R, G, B, or A) * is adjusted by delta. Note: the BufferedImage must be of type BufferedImage.TYPE_INT_ARGB. * @param src BufferedImage of type BufferedImage.TYPE_INT_ARGB. * @param colorIndex 0=red, 1=green, 2=blue, 3= alpha * @param delta amount to change component * @return */ public static BufferedImage adjustAColor(BufferedImage src,int colorIndex, int delta) { int w = src.getWidth(); int h = src.getHeight(); assert(src.getType()==BufferedImage.TYPE_INT_ARGB); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { int rgb = src.getRGB(x,y); java.awt.Color color= new java.awt.Color(rgb,true); int red=color.getRed(); int green=color.getGreen(); int blue=color.getBlue(); int alpha=color.getAlpha(); switch (colorIndex) { case 0: red=adjustColor(red,delta); break; case 1: green=adjustColor(green,delta); break; case 2: blue=adjustColor(blue,delta); break; case 3: alpha=adjustColor(alpha,delta); break; default: throw new IllegalStateException(); } java.awt.Color adjustedColor=new java.awt.Color(red,green,blue,alpha); src.setRGB(x,y,adjustedColor.getRGB()); int gottenColorInt=src.getRGB(x,y); java.awt.Color gottenColor=new java.awt.Color(gottenColorInt,true); assert(gottenColor.getRed()== red); assert(gottenColor.getGreen()== green); assert(gottenColor.getBlue()== blue); assert(gottenColor.getAlpha()== alpha); } return src; } private static int adjustColor(int value255, int delta) { value255+= delta; if (value255<0) { value255=0; } else if (value255>255) { value255=255; } return value255; }

More Related questions