LWJGL Forum

Programming => Lightweight Java Gaming Library => Topic started by: paul_nicholls on May 14, 2012, 12:16:03

Title: Editing PNGDecoder image colors?
Post by: paul_nicholls on May 14, 2012, 12:16:03
Hi all,
 I have been following the LWJGL tutorial here to load a PNG file and use it as an OpenGL texture:
http://www.lwjgl.org/wiki/index.php?title=Loading_PNG_images_with_TWL%27s_PNGDecoder

I got that working ok, but now I want to test the pixels in that decoded image to see if it matches a colorkey color (r,g,b), and if so, change that matching pixel's alpha to 0.  This is prior to setting the OpenGL texture afterwards.

I guess I need to use the buf.get(index) method to get the R,G,B components of each pixel, test against the colorkey r,g,b, and the use the buf.put(index,0) to set the alpha, but I am not sure how to get this working...

I am rather new to Java.

Any ideas?
cheers,
Paul
Title: Re: Editing PNGDecoder image colors?
Post by: matheus23 on May 14, 2012, 12:36:48
Thats right, I assume, you want to set Alpha to 0, if you have the colors 255, 255, 255?

The bigger problem is, that you only have a Buf with (R, G, B) values, but you need alpha too (R, G, B, A).
That means, you have to copy the Buffer 1 into Buffer 2, which is a bit bigger.



public static ByteBuffer convert(ByteBuffer data) {
final byte alphaRed = (byte)255;
final byte alphaGreen = (byte)255;
final byte alphaBlue = (byte)255;
ByteBuffer converted = BufferUtils.createByteBuffer((data.capacity()/3)*4);
int dataIndex = 0;
int convertedIndex = 0;
for (int i = 0; i < data.capacity()/3; i++) {
dataIndex = i*3;
convertedIndex = i*4;
byte red = data.get(dataIndex+0);
byte green = data.get(dataIndex+1);
byte blue = data.get(dataIndex+2);
converted.put(convertedIndex+0, red);
converted.put(convertedIndex+1, green);
converted.put(convertedIndex+2, blue);
if (red == alphaRed && green == alphaGreen && blue == alphaBlue) {
converted.put(convertedIndex+3, (byte)0);
} else {
converted.put(convertedIndex+3, (byte)255);
}
}
converted.flip();
return converted;
}


But I just thought of another version... I'll post it later.
Also, this version is untested.
Title: Re: Editing PNGDecoder image colors?
Post by: matheus23 on May 14, 2012, 12:37:56
If the last version did not work, try this one:



public static ByteBuffer convert(ByteBuffer data) {
final byte alphaRed = (byte)255;
final byte alphaGreen = (byte)255;
final byte alphaBlue = (byte)255;
ByteBuffer converted = BufferUtils.createByteBuffer((data.capacity()/3)*4);
for (int i = 0; i < data.capacity(); i++) {
byte red = data.get();
byte green = data.get();
byte blue = data.get();
converted.put(red);
converted.put(green);
converted.put(blue);
if (red == alphaRed && green == alphaGreen && blue == alphaBlue) {
converted.put((byte)0);
} else {
converted.put((byte)255);
}
}
converted.flip();
return converted;
}


I think its coded much better.
Title: Re: Editing PNGDecoder image colors?
Post by: paul_nicholls on May 14, 2012, 20:37:22
Nice! Thanks for the code matheus23, I will try it out a bit later on :)

Just one question though:

Since in the tutorial they use RGBA as the image decoding format and OpenGL texture format, doesn't that mean that the ByteBuffer with the image in it already has 4 bytes per pixel (RGBA), not 3 (RGB)?

Of course my assumption could be completely wrong as my code I tried before posting here just didn't work and having only RGB bytes per pixel might explain that haha
Title: Re: Editing PNGDecoder image colors?
Post by: paul_nicholls on May 15, 2012, 02:36:23
hmm...for some reason I couldn't get your code (latest) to work properly, it gave a buffer underflow error (I think..)

Anyway, I managed to do it this way (using Oxygene for Java -a Pascal derivative that compiles to Java Byte code):

method DoColorKey(aData: ByteBuffer; aR,aG,aB: Integer);
var
  i       : Integer;
  r,g,b : Byte;
begin
  i := 0;
  while i < aData.capacity do
  begin
    r := aData.get(i+0);
    g := aData.get(i+1);
    b := aData.get(i+2);

    if (r = Byte(aR)) and (g = Byte(aG)) and (b = Byte(aB)) then
      aData.put(i+3,Byte(0));

    inc(i,4);
  end;
end;


Thanks for the help :)

Maybe this will help someone else!!

cheers,
Paul
Title: Re: Editing PNGDecoder image colors?
Post by: matheus23 on May 15, 2012, 15:51:07
Quote from: paul_nicholls on May 15, 2012, 02:36:23
hmm...for some reason I couldn't get your code (latest) to work properly, it gave a buffer underflow error (I think..)

Anyway, I managed to do it this way (using Oxygene for Java -a Pascal derivative that compiles to Java Byte code):

method DoColorKey(aData: ByteBuffer; aR,aG,aB: Integer);
var
  i       : Integer;
  r,g,b : Byte;
begin
  i := 0;
  while i < aData.capacity do
  begin
    r := aData.get(i+0);
    g := aData.get(i+1);
    b := aData.get(i+2);

    if (r = Byte(aR)) and (g = Byte(aG)) and (b = Byte(aB)) then
      aData.put(i+3,Byte(0));

    inc(i,4);
  end;
end;


Thanks for the help :)

Maybe this will help someone else!!

cheers,
Paul

Okey :) Glad, I gave you an idea :)