color format inconsistency?

K

Krishan

hi,

maybe i've been looking at this for too long, but i think i found a
strange thing in the JDK. take the color class and use the method
getRGB() on a color, you get an integer with the color samples in ARGB
(high order bits first) format, e.g.

Color.RED.getRGB(); gives 0xffff0000


then take the raster class with say the SinglePixelPackedSampleModel
(the following line gives u a raster with a databuffer holding width x
height x 4 samples while 4 samples represent the color value for a
stored pixel -- so it's SinglePixelPacked since the 4 color bands each
have a depth of 8bit, that makes 32bit/pixel and the databuffer's
integral type (TYPE_INT) matches this lovely)

Raster ras = Raster.createPackedRaster(DataBuffer.TYPE_INT,width,height,4,8,null);

the raster methods (setPixel) basically don't care about the color
format, as long as it's some 32bit value they'll eat it, same with the
setSample methods - they just navigate you through the bitmaze, ähm
array


so it's somebody else's task to interpret the values in the raster
right, let me introduce BufferedImage which enables you to command
exactly that, here's the code

BufferedImage bImg = new
BufferedImage(ras.getWidth(),ras.getHeight(),BufferedImage.TYPE_INT_ARGB);

along TYPE_INT_ARGB there are other types, those of interest here are
just

TYPE_INT_ARGB - MISLEADING, it's really ABGR (high order first), or
RGBA (low order first), like the api help will tell you
TYPE_4BYTE_ABGR - CONSISTENT at once, this actually interprets ABGR
(low order bits first, or RGBA (high order first)

(now low order bits first:)
why can't i just tell a java BufferedImage (colorformats either RGBA,
or ABGR) to take an java Color (colorformat BGRA) and display it
right, this sucks


there are two ways around this, but my guts tell me one shouldn't have
to bother with this and be changed in the api design

1) take the 32 bit value from getRGB(), left shifting it by 8 and
putting the alpha value in the low order 8bits of the integer

int color = Color.RED.geRGB();
color <<= 8;
color |= (optalpha & 0xFF);

now put the value in the raster and tell your buffered image to
interpret the data as TYPE_4BYTE_ABGR - WOW you've done it, thanks
SUN, this is really easy

2) tell the raster to switch things around - u use a different
constructor for that purpose

Raster ras = Raster.createPackedRaster(DataBuffer.TYPE_INT,r.width,r.height,new
int[]{0xFF<<16,0xFF<<8,0xFF<<0,0xFF<<24},null);

this switches your BGRA color class output into RGBA style (both low
order bits first), so that one can safely use TYPE_INT_ARGB for the
BufferedImage (which actually is RGBA as discussed above)

of course if u design your own 4-band integer array, u have to
consider this and do it the way the getRGB() method spits out it's
Color value - u want to put RED at (x,y) (3,3) on the raster, use

ras.getSampleModel().setPixel(3,3,new int[]{BLUEVAL, GREENVAL, REDVAL,
ALPHAVAL}, ras.getDataBuffer());

this doesn't apply to the first solution - there it's lovely ARGB for
arrays, just like the BufferedImageType


=============================================================================
next thing: there is a setPixel method in the SampleModelMethods that
takes a float array, just gorgeous u think - it'll propaply behave
like the Color constructor that takes float arguments - and scale your
fractional values between [0.0,1.0] to range [0,255]

of course all it does is casting away the fractional part and putting
that as the value for a color-band-sample


=============================================================================
if u know better, please tell me!

is it on purpose or is it just a designflaw?
i also appreciate any better solutions

what i'm doing?
implementing stuff that's already there - like drawing antialiasing
lines for study - works wonderfully, but i realized that this get's
really sloooow (no wonder, there's no setpixel operation in
java.awt.graphics, so one had to cripple drawLine(x1,y1,x2,y2) to
drawLine(x1,y1,x1,y1))

now i'm working offscreen on this raster and then blitting it to the
screen
is there a better way to intersect the (re-)drawing process in java
for such low level algorithms, making it even faster?

i also tried getting SurfaceData surData =
((SunGraphics2D)g).getSurfaceData().getRaster()...
but this feature isn't implemented yet, SUN tells me via Exception


thx in advance
 
K

Krishan

of course if u design your own 4-band integer array, u have to
consider this and do it the way the getRGB() method spits out it's
Color value - u want to put RED at (x,y) (3,3) on the raster, use

ras.getSampleModel().setPixel(3,3,new int[]{BLUEVAL, GREENVAL, REDVAL,
ALPHAVAL}, ras.getDataBuffer());

this is wrong actually, oops ;-) - the order in which the color
components have to be must comply to whichever you want to interpret the
data later on, i used TYPE_INT_ARGB when creating a BufferedImage, so
this demands component order like this 0xaabbggrr - with low order first
the correct setPixel call is then

ras.getSampleModel().setPixel(3,3,new int[]{REDVAL, GREENVAL, BLUEVAL,
ALPHAVAL}, ras.getDataBuffer());

================================================================================
i made a little progress, but could someone tell me short and precise
what are the differences between

ColorModel - with a BufferedImage
ColorSpace - with a ColorModel
SampleModel - in conjuntion with a Raster

the api help of BufferedImage notes that the image consists of a
ColorModel and Raster - how do these two play together? any pointers to
good reference?
 
T

Tim Tyler

: what i'm doing?
: implementing stuff that's already there - like drawing antialiasing
: lines for study - works wonderfully, but i realized that this get's
: really sloooow (no wonder, there's no setpixel operation in
: java.awt.graphics, so one had to cripple drawLine(x1,y1,x2,y2) to
: drawLine(x1,y1,x1,y1))

The lack of such a method does seem to be pretty dumb.
 

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