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.
Thomas Fritsch - 06 Oct 2006 18:21 GMT
[...]
> float hue, sat, bri;
> int iRGB;
[quoted text clipped - 17 lines]
> }
> }
[...]
> 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

Signature
Thomas
Tom Peel - 06 Oct 2006 23:54 GMT
Thomas Fritsch schrieb:
> [...]
>> float hue, sat, bri;
[quoted text clipped - 52 lines]
> 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.
--
Thomas Fritsch - 08 Oct 2006 15:08 GMT
"Tom Peel" <nottandp@freenet.de> schrieb:
> 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
[quoted text clipped - 9 lines]
> 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

Signature
Thomas