Change alpha value of BufferedImage?

How to change global alpha value of BufferedImage in Java? (IE makes every pixel in the image that has an alpha value of 100, has an alpha value of 80)

+7
java graphics bufferedimage
source share
6 answers

I do not believe that there is a simple command for this. Several variants:

The first is the easiest to implement, IMO.

+4
source share

@Neil Coffey: Thank you, I also searched for this; however, your code didn’t work very well for me (white background turned black).

I encoded something like this and it works fine:

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 BufferedImage.TYPE_INT_ARGB.

I am changing alpha with setAlpha ((byte) 125); the alpha range is now 0-255.

Hope someone finds this helpful.

+9
source share

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

Alphacomposite

As @Michael's excellent plan noted, AlphaComposite operation can modify the alpha channel. But only for certain reasons that I find difficult to understand:

enter image description here

formula for how the operation "over" affects the alpha channel. Moreover, it also affects the RGB channels, so if you have color data that should be unchanged, AlphaComposite is not the answer.

BufferedImageOps

LookupOp

There are several varieties of BufferedImageOp (see 4.10.6 here ). In a more general case, the OP task can be performed using LookupOp , which requires arrays of building objects. To change only the alpha channel, put an identification array (an array where the table is [i] = i) for RGB channels, and a separate array for the alpha channel. Fill in the last array table[i] = f(i) , where f() is the function with which you want to match the new value from the old alpha value. For example. if you want "every pixel in the image with an alpha value of 100 has an alpha value of 80," set table[100] = 80 . (The full range is from 0 to 255.) See how to increase the opacity in Gaussian blur for a code sample.

Rescaleop

But for a subset of these cases, there is an easier way to do this, which does not require tuning the lookup table. If f() is a simple, linear function, use RescaleOp . For example, if you want to set newAlpha = oldAlpha - 20 , use RescaleOp with scaleFactor 1 and an offset of -20. If you want to set newAlpha = oldAlpha * 0.8 , use scaleFactor 0.8 and an offset of 0. In any case, you will again have to provide dummy scale factors and offsets for 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 that illustrate the principles well, but are not specific to the alpha channel.

Both RescaleOp and LookupOp allow modification of the BufferedImage in place.

+4
source share

for a more enjoyable alpha change effect, you can use relative alpha change per pixel (instead of static typing 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); } } } 
+2
source share

I am 99% sure that methods that claim to deal with an RGB value packaged in int actually deal with ARGB. So you should be able 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 can use methods to extract blocks of pixel values.

+1
source share

You may need to first copy BufferedImage to an image of type BufferedImage.TYPE_INT_ARGB . If your image is of the type, say, BufferedImage.TYPE_INT_RGB , then the alpha component will not be installed correctly. If your BufferedImage 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; }

0
source share

All Articles