Изоляция красного / зеленого / синего канала в Java BufferedImage

Как изолировать красный / зеленый / синий канал в 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;
}`

Под изоляцией канала я подразумеваю, что если для изоляции выбран, например, красный канал, то отображается только красный компонент изображения!

2 ответа

Решение

Color в Java определяется в виде упакованного целого числа, то есть 32-разрядного целого числа, первые 8 битов являются альфа-каналом, следующие 8 - красным, следующие 8 - зеленым и последние 8 - синим.

Предположим, что следующее представляет собой 32-разрядное целое число, представляющее цвет. Затем

AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB
^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;
}

Примечание: я ORed newPixelперед каждым компонентом, чтобы разрешить отображение нескольких каналов одновременно, т.е. вы можете отображать красный и зеленый с выключенным синим.


ОБНОВИТЬ

Вторая ошибка, которую вы получаете, связана с тем, что вы не сбрасываете значение 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 для получения красного, зеленого, синего и альфа.

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

Этот код будет работать быстрее, так как он не создает 4 Color объекты для каждого пикселя в исходном изображении

Попробуй это:

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);
    }
}
Другие вопросы по тегам