0

I'm currently having an issue with alpha channels when reading PNG files with 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);

However, when trying to read values from the pixel array by bit shifting as seen below, the alpha channel is always returning -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

By Googling the problem I understand that the BufferedImage type needs to be defined as below to allow for the alpha channel to work:

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

But ImageIO.read(...) returns a BufferedImage without giving the option to specify the image type. So how can I do this? Any help is much appreciated.

Thanks in advance

Harald K
  • 26,314
  • 7
  • 65
  • 111
JxstJxck
  • 11
  • 3
  • I'm not 100% sure, but I think you "int unpacking" code might be wrong. I used `(pixel >> 24) & 0xff` (where `pixel` is the rgba value of a specific pixel) and it worked fine. I compared this with the results of `java.awt.Color` and they worked fine. I "stole" the "extraction" code directly from `java.awt.Color`, this is, yet another reason, I tend not to perform these operations this way, it's to easy to screw them up – MadProgrammer Oct 22 '18 at 22:18
  • You may also want to have a look at [How to convert get.rgb(x,y) integer pixel to Color(r,g,b,a) in Java?](https://stackoverflow.com/questions/2534116/how-to-convert-get-rgbx-y-integer-pixel-to-colorr-g-b-a-in-java) – MadProgrammer Oct 22 '18 at 22:20

2 Answers2

1

I think, your "int unpacking" code might be wrong.

I used (pixel >> 24) & 0xff (where pixel is the rgba value of a specific pixel) and it worked fine.

I compared this with the results of java.awt.Color and they worked fine.

I "stole" the "extraction" code directly from java.awt.Color, this is, yet another reason, I tend not to perform these operations this way, it's to easy to screw them up

And my awesome test code...

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: Before some one tells that this is inefficient, I wasn't going for efficiency, I was going for quick to write

You may also want to have a look at How to convert get.rgb(x,y) integer pixel to Color(r,g,b,a) in Java?, which I also used to validate my results

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
1

I think the problem is that you're using arithmetic shift (>>) instead of logical shift (>>>). Thus 0xff000000 >> 24 becomes 0xffffffff (i.e. -1)

Tadeusz Sznuk
  • 994
  • 6
  • 9