【问题标题】:Isolating Red/Green/Blue Channel in Java BufferedImage在 Java BufferedImage 中隔离红/绿/蓝通道
【发布时间】:2013-05-17 21:28:25
【问题描述】:

如何在 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;
}`

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

【问题讨论】:

    标签: java image-processing colors bufferedimage color-channel


    【解决方案1】:

    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&lt;&lt;24 | red&lt;&lt;16 | green&lt;&lt;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进行了OR操作,以允许同时显示多个通道,即您可以在关闭蓝色的情况下显示红色和绿色。


    更新

    您遇到的第二个错误是由于您没有在每次迭代后重置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;
    

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

    【讨论】:

    • 嗯,很好的导师,非常感谢你,但现在我加载了一些图像,当我应用滤色器时,我得到的图像填充了那种颜色 - 图像消失,我得到彩色矩形(如果我选择红色滤镜,我得到图像大小的红色矩形,如果我选择绿色滤镜,我得到绿色矩形,蓝色滤镜也是如此)
    【解决方案2】:

    试试这个:

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

    【讨论】:

      猜你喜欢
      • 2019-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-09
      • 1970-01-01
      • 2016-03-20
      • 1970-01-01
      相关资源
      最近更新 更多