Advice needed - BufferedImage, Raster, SinglePixelPackedSampleModel,DataBufferInt, Color

T

Tom Peel

I'm trying to use these classes directly for the first time and not
quite getting the results I expect. The application reads a file
containing terrain altitude data and is supposed to display an image
with the terrain altitudes represented by different colours- green
fading to yellow to brown.

// I create a SampleModel, DataBuffer and WritableRaster:

SampleModel sm = new SinglePixelPackedSampleModel(
DataBuffer.TYPE_INT, stdX, stdY, new int[] {0xFF000000, 0xFF0000,
0xFF00, 0xFF});

DataBuffer db = new DataBufferInt(stdX*stdY);

WritableRaster wr = Raster.createWritableRaster(sm, db, null);

float hue, sat, bri;
int iRGB;
int hgt;
float hgtff;
int k = 0;

// this loop maps the terrain data from hgtdata in HSB values and sets
the elements in the DataBuffer:

for (iy = 0; iy<stdY; iy++) {
for (ix = 0; ix<stdX; ix++) {
hgt = hgtdata[ix][iy];
hgtff = hgt/2000.0F;
hue = 0.22F - 0.05F*hgtff;
sat = 1.00F - 0.45F*hgtff;
bri = 1.00F - 0.13F*hgtff;
iRGB = Color.HSBtoRGB(hue, sat, bri);
db.setElem(k, iRGB);
k++;
}
}
bi = new BufferedImage(stdX, stdY, BufferedImage.TYPE_INT_ARGB);
bi.setData(wr);

// at another part of the program there is a PaintComponent that calls
g2d.drawImage(bi, . . .)

The effect is that the image is drawn, but the colours are wrong.
Looking at the loop with Eclipse debug, I see for example a value of
hgt=136 giving a hue of 0.22F, which should be bright green, and iRGB =
-4716291. The resulting colour however is an extremely washed out
pale purple-magenta. The values in the hgtdata array are correct, BTW.
Reading the Color.HSBtoRGB documentation, hue=0.22F should give me 80
degrees, which is green.

Is the bitmap array in SinglePixelPackedSampleModel correct? I could not
find any examples. Should I be setting the alpha chanel? I really don't
need alpha, but I'm having difficulty understanding the intricacies of
the raster system, and using ARGB seems to be easiest. I tried RGB but
had no success getting the program to work at all.

Help/advice much appreciated.

T.
 
T

Thomas Fritsch

Tom Peel wrote:
[...]
float hue, sat, bri;
int iRGB;
int hgt;
float hgtff;
int k = 0;

// this loop maps the terrain data from hgtdata in HSB values and sets
the elements in the DataBuffer:

for (iy = 0; iy<stdY; iy++) {
for (ix = 0; ix<stdX; ix++) {
hgt = hgtdata[ix][iy];
hgtff = hgt/2000.0F;
hue = 0.22F - 0.05F*hgtff;
sat = 1.00F - 0.45F*hgtff;
bri = 1.00F - 0.13F*hgtff;
iRGB = Color.HSBtoRGB(hue, sat, bri);
db.setElem(k, iRGB);
k++;
}
} [...]
The effect is that the image is drawn, but the colours are wrong.
Looking at the loop with Eclipse debug, I see for example a value of
hgt=136 giving a hue of 0.22F, which should be bright green, and iRGB =
-4716291. The resulting colour however is an extremely washed out
pale purple-magenta. The values in the hgtdata array are correct, BTW.
Using this code snippet
hgt = 136; // your example
hgtff = hgt/2000.0F;
hue = 0.22F - 0.05F*hgtff;
sat = 1.00F - 0.45F*hgtff;
bri = 1.00F - 0.13F*hgtff;
iRGB = Color.HSBtoRGB(hue, sat, bri);
System.out.println("irgb = " + iRGB +
" = 0x" + Integer.toHexString(iRGB));
System.out.println(new Color(iRGB));
I get the output
iRGB = -4981496 = 0xffb3fd08
java.awt.Color[r=179,g=253,b=8]
but not your value iRGB = -4716291.
The color has much red, much green, almost no blue (==> bright yellow),
but it is not your bright green.

Reading the Color.HSBtoRGB documentation, hue=0.22F should give me 80
degrees, which is green.
I couldn't verify this (or find anything) in the Color.HSBtoRGB
documentation. In my opinion it is:
0 degree = red
60 degree = yellow
120 degree = green
180 degree = cyan
240 degree = blue
300 degree = magenta
360 degree = red
 
T

Tom Peel

Thomas said:
Tom Peel wrote:
[...]
float hue, sat, bri;
int iRGB;
int hgt;
float hgtff;
int k = 0;

// this loop maps the terrain data from hgtdata in HSB values and sets
the elements in the DataBuffer:

for (iy = 0; iy<stdY; iy++) {
for (ix = 0; ix<stdX; ix++) {
hgt = hgtdata[ix][iy];
hgtff = hgt/2000.0F;
hue = 0.22F - 0.05F*hgtff;
sat = 1.00F - 0.45F*hgtff;
bri = 1.00F - 0.13F*hgtff;
iRGB = Color.HSBtoRGB(hue, sat, bri);
db.setElem(k, iRGB);
k++;
}
} [...]
The effect is that the image is drawn, but the colours are wrong.
Looking at the loop with Eclipse debug, I see for example a value of
hgt=136 giving a hue of 0.22F, which should be bright green, and iRGB
= -4716291. The resulting colour however is an extremely washed out
pale purple-magenta. The values in the hgtdata array are correct, BTW.
Using this code snippet
hgt = 136; // your example
hgtff = hgt/2000.0F;
hue = 0.22F - 0.05F*hgtff;
sat = 1.00F - 0.45F*hgtff;
bri = 1.00F - 0.13F*hgtff;
iRGB = Color.HSBtoRGB(hue, sat, bri);
System.out.println("irgb = " + iRGB +
" = 0x" + Integer.toHexString(iRGB));
System.out.println(new Color(iRGB));
I get the output
iRGB = -4981496 = 0xffb3fd08
java.awt.Color[r=179,g=253,b=8]
but not your value iRGB = -4716291.
The color has much red, much green, almost no blue (==> bright yellow),
but it is not your bright green.

Reading the Color.HSBtoRGB documentation, hue=0.22F should give me 80
degrees, which is green.
I couldn't verify this (or find anything) in the Color.HSBtoRGB
documentation. In my opinion it is:
0 degree = red
60 degree = yellow
120 degree = green
180 degree = cyan
240 degree = blue
300 degree = magenta
360 degree = red

Hi Thomas
You are correct that 120° is also green, but it is a much darker
shade. I just put your RGB values from your test program into Photoshop,
and this does give a bright green colour- leaf green. Photoshop shows
the HSB values 78°/97%/99% which is close to what I expect.
I'm not sure why your decimal iRGB is different- I also wrote down the
hex value, and it is almost the same as the value you got- except the
last two bytes are swapped round!!

I've just been experimenting and I'm starting to wonder if the
green/blue values are swapped? But how? It's 1AM and I have to stop now.

T.
--
 
T

Thomas Fritsch

Tom Peel said:
I'm trying to use these classes directly for the first time and not quite
getting the results I expect. The application reads a file containing
terrain altitude data and is supposed to display an image with the terrain
altitudes represented by different colours- green fading to yellow to
brown.

// I create a SampleModel, DataBuffer and WritableRaster:

SampleModel sm = new SinglePixelPackedSampleModel( DataBuffer.TYPE_INT,
stdX, stdY, new int[] {0xFF000000, 0xFF0000, 0xFF00, 0xFF});

DataBuffer db = new DataBufferInt(stdX*stdY);
WritableRaster wr = Raster.createWritableRaster(sm, db, null); [...]
bi = new BufferedImage(stdX, stdY, BufferedImage.TYPE_INT_ARGB);
bi.setData(wr);

// at another part of the program there is a PaintComponent that calls
g2d.drawImage(bi, . . .) [...]

Is the bitmap array in SinglePixelPackedSampleModel correct?
It is one way of doing. Another approach coming to my mind is:
Construct a WritableRaster with a DataBuffer directly containg your height
values (as int[], or better as short[]). Create a ColorModel (probably an
IndexColorModel) for converting a raster "height" value to an RGB value.
(You may also consider using ColorModel#createCompatibleWritableRaster)
Finally construct the image with
new BufferedImage(colorModel, raster, false, null);
Of course this approach has the limitation, that only colors from your
"height"
color spectrum are representable.
I could not
find any examples. Should I be setting the alpha chanel? I really don't
need alpha, but I'm having difficulty understanding the intricacies of the
raster system, and using ARGB seems to be easiest. I tried RGB but had no
success getting the program to work at all.
IMHO it is hard (if not impossible) to grasp the powerful concepts behind
BufferedImage/Raster/DataBuffer from the API docs and from Sun's tutorial
https://java.sun.com/docs/books/tutorial/2d/TOC.html
alone. A good book is definitely needed. The one I found most useful was
http://www.amazon.com/Java-2D-Graphics-Jonathan-Knudsen/dp/1565924843
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top