更改BufferedImage的alpha值?

时间:2009-03-19 00:07:45

标签: java graphics bufferedimage

如何在Java中更改BufferedImage的全局alpha值? (I.E.使图像中每个像素值为100的像素的alpha值为80)

6 个答案:

答案 0 :(得分:9)

@Neil Coffey: 谢谢,我一直在寻找这个;但是,你的代码对我来说效果不好(白色背景变黑)。

我编写了类似这样的内容并且效果很好:

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);            

        }

    }
}

其中obj_img为BufferedImage.TYPE_INT_ARGB。

我用setAlpha((byte)125)改变alpha; alpha范围现在是0-255。

希望有人觉得这很有用。

答案 1 :(得分:4)

我不相信有一个简单的命令可以做到这一点。一些选择:

第一个是最简单的实施,IMO。

答案 2 :(得分:4)

这是一个老问题,所以我不是为了OP而回答,而是为了那些像我这样后来发现这个问题的人。

的AlphaComposite

正如@ Michael提到的优秀大纲,AlphaComposite操作可以修改alpha通道。但只是在某些方面,对我来说有点难以理解:

enter image description here

the formula,表示“over”操作如何影响alpha通道。此外,这也会影响RGB通道,因此如果您的颜色数据需要保持不变,则AlphaComposite不是答案。

的BufferedImageOp

LookupOp

BufferedImageOp有几种(见4.10.6 here)。在更一般的情况下,OP的任务可以由LookupOp来满足,这需要构建查找数组。要仅修改Alpha通道,请为RGB通道提供一个标识数组(table [i] = i的数组),并为Alpha通道提供单独的数组。使用table[i] = f(i)填充后一个数组,其中f()是您要从旧alpha值映射到new的函数。例如。如果要“使图像中的每个像素值为100的alpha值为80”,请设置table[100] = 80。 (完整范围是0到255.)有关代码示例,请参阅how to increase opacity in gaussian blur

RescaleOp中

但是对于这些情况的一个子集,有一种更简单的方法,它不需要设置查找表。如果f()是一个简单的线性函数,请使用RescaleOp。例如,如果要设置newAlpha = oldAlpha - 20,请使用scaleFactor为1且偏移量为-20的RescaleOp。如果要设置newAlpha = oldAlpha * 0.8,请使用scaleFactor为0.8,偏移量为0.在任何一种情况下,您都必须为RGB通道提供虚拟scaleFactors和偏移量:

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

再次参阅4.10.6 here,了解一些可以很好地说明原理的示例,但不是特定于Alpha通道。

RescaleOpLookupOp都允许就地修改BufferedImage。

答案 3 :(得分:3)

对于看起来更漂亮的alpha变化效果,你可以使用每个像素的相对alpha变化(而不是静态集,或剪裁线性)

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);            
        }
    }
}

答案 4 :(得分:1)

我99%确定声称处理打包到int中的“RGB”值的方法实际上处理ARGB。所以你应该能够做到这样的事情:

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);
  }
}

对于速度,您可以使用这些方法来检索像素值块。

答案 5 :(得分:0)

您可能需要先将BufferedImage复制到BufferedImage.TYPE_INT_ARGB类型的图像。如果您的图片类型为BufferedImage.TYPE_INT_RGB,则无法正确设置alpha分量。如果您的BufferedImage类型为BufferedImage.TYPE_INT_ARGB,则下面的代码可以正常工作。 /** * 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; }