Альфа-канал игнорируется при использовании ImageIO.read () - PullRequest
0 голосов
/ 23 октября 2018

У меня сейчас проблема с альфа-каналами при чтении файлов PNG с ImageIO.read(...)

fileInputStream = new FileInputStream(path);
BufferedImage image = ImageIO.read(fileInputStream);

//Just copying data into an integer array
int[] pixels = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, width, height, pixels, 0, width);

Однако, при попытке прочитать значения из массива пикселей путем сдвига битов, как показано ниже, альфаканал всегда возвращает -1

int a = (pixels[i] & 0xff000000) >> 24;
int r = (pixels[i] & 0xff0000) >> 16;
int g = (pixels[i] & 0xff00) >> 8;
int b = (pixels[i] & 0xff);
//a = -1, the other channels are fine

При поиске в Google проблемы я понимаю, что для определения альфа-канала необходимо определить тип BufferedImage, как показано ниже:

BufferedImage image = new BufferedImage(width, height BufferedImage.TYPE_INT_ARGB);

Но ImageIO.read(...) возвращает BufferedImage без предоставления возможности указать тип изображения.Так как я могу это сделать?Любая помощь очень ценится.

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Я думаю, что проблема в том, что вы используете арифметическое смещение (>>) вместо логического смещения (>>>).Таким образом, 0xff000000 >> 24 становится 0xffffffff (то есть -1)

0 голосов
/ 23 октября 2018

Я думаю, ваш код "int unpacking" может быть неправильным.

Я использовал (pixel >> 24) & 0xff (где pixel - значение rgba определенного пикселя), и он работал нормально.

Я сравнил это с результатами java.awt.Color, и они работали нормально.

Я «украл» код «извлечения» непосредственно из java.awt.Color, это, еще одна причина, я склонен не выполнять эти операции таким образом, их легко испортить

И мой потрясающий тестовый код ...

BufferedImage image = ImageIO.read(new File("BYO image"));
int width = image.getWidth();
int height = image.getHeight();
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        int pixel = image.getRGB(x, y);
        //value = 0xff000000 | rgba;
        int a = (pixel >> 24) & 0xff;
        Color color = new Color(pixel, true);
        System.out.println(x + "x" + y + " = " + color.getAlpha() + "; " + a);
    }
}

nb: Прежде чем кто-то скажет, что это неэффективно, я не собирался повышать эффективность, я собирался быстро написать

Вы также можете взглянуть на Как преобразовать целочисленный пиксель get.rgb (x, y) в Color (r, g, b, a) в Java? , которыйЯ также использовал для проверки своих результатов

...