2

如何在 BufferedImage 中隔离红/绿/蓝通道:我有以下代码不起作用:`

public static BufferedImage isolateChannel(BufferedImage image,
        EIsolateChannel channel)
{
    BufferedImage result=new BufferedImage(image.getWidth(),
            image.getHeight(),
            image.getType());
    int iAlpha=0;
    int iRed=0;
    int iGreen=0;
    int iBlue=0;
    int newPixel=0;

    for(int i=0; i<image.getWidth(); i++)
    {
        for(int j=0; j<image.getHeight(); j++)
        {
            iAlpha=new Color(image.getRGB(i, j)).getAlpha();
            iRed=new Color(image.getRGB(i, j)).getRed();
            iGreen=new Color(image.getRGB(i, j)).getGreen();
            iBlue=new Color(image.getRGB(i, j)).getBlue();

            if(channel.equals(EIsolateChannel.ISOLATE_RED_CHANNEL))
            {
                newPixel=iRed;
            }

            if(channel.equals(EIsolateChannel.ISOLATE_GREEN_CHANNEL))
            {
                newPixel=iGreen;
            }

            if(channel.equals(EIsolateChannel.ISOLATE_BLUE_CHANNEL))
            {
                newPixel=iBlue;
            }

            result.setRGB(i,
                    j,
                    newPixel);
        }
    }

    return result;
}`

隔离通道是指如果选择红色通道进行隔离,例如,仅显示图片的红色分量!

4

2 回答 2

3

Color在java中定义为一个压缩整数,即在一个32位整数中,前8位是alpha,接下来的8位是红色,接下来的8位是绿色,最后8位是蓝色。

假设下面是一个表示颜色的 32 位整数。那么,

AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB
^Alpha   ^Red     ^Green   ^Blue

也就是说,alpha、red、green 和 blue 基本上都是 8 位,值从 0 到 255(颜色范围)。因此,当您想将这些单独的组件组合回 32 位整数颜色时,您应该编写

color=alpha<<24 | red<<16 | green<<8 | blue

因此按照规则将代码更改为以下

if(channel.equals(EIsolateChannel.ISOLATE_RED_CHANNEL))
{
    newPixel = newPixel | iRed<<16; 
    //Can also write newPixel=iRed , since newPixel is always 0 before this
}

if(channel.equals(EIsolateChannel.ISOLATE_GREEN_CHANNEL))
{
    newPixel = newPixel | iGreen<<8;
}

if(channel.equals(EIsolateChannel.ISOLATE_BLUE_CHANNEL))
{
    newPixel = newPixel | iBlue;
}

注意:我newPixel在每个组件之前都进行了 ORed,以允许同时显示多个通道,即您可以在关闭蓝色的情况下显示红色和绿色。


更新

您遇到的第二个错误是由于您没有newPixel在每次迭代后重置 的值。因此,要修复它,请newPixel=0在循环中添加该行。你的代码应该是

newPixel=0; //Add this line
iAlpha=new Color(img.getRGB(x, y)).getAlpha();
iRed=new Color(img.getRGB(x, y)).getRed();
iGreen=new Color(img.getRGB(x, y)).getGreen();
iBlue=new Color(img.getRGB(x, y)).getBlue();

为了提高效率,我建议bitshifts用于获取红色、绿色、蓝色和 alpha。

int rgb = img.getRGB(x,y);
iAlpha = rgb>>24 & 0xff;
iRed = rgb >>16 & 0xff;
iGreen = rgb>>8 & 0xff;
iBlue = rgb & 0xff;

此代码将运行得更快,因为它不会Color为源图像中的每个像素创建 4 个对象

于 2013-05-22T17:57:13.463 回答
0

试试这个:

int width = bufferedImage.getWidth(), height = bufferedImage.getHeight();
Object dataElements = null;
Raster raster = bufferedImage.getRaster();
ColorModel colorModel = bufferedImage.getColorModel();
int red, blue, green, alpha;
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {

        dataElements = raster.getDataElements(x, y, dataElements);
        // extract colors
        red   = colorModel.getRed(dataElements);
        blue  = colorModel.getBlue(dataElements);
        green = colorModel.getGreen(dataElements);
        alpha = colorModel.getAlpha(dataElements);
    }
}
于 2016-09-28T21:12:40.227 回答