problem with creating JAI grayscale image

J

Java_New

Hi all,

I need your help.

I am trying to convert a 12 bits grayscale image to BufferedImage from
byte array. But the output image was very poor contrasted. I tried
everything I could think about (by using lut operator, indexColorModel,
etc.) to correct it. There was still no luck for me. The code is shown
below:

short temp[] = new short[width*height];
int index = 0;
try{
byte data[] = new byte[pixelDataLength];
BufferedFileInputStream.read(data);
for( int i =0; i<temp.length;i++){
temp = (short) (data[index++]+((data[index++])<<8));
}
}catch(IOException ex){}

DataBufferUShort dbs= new DataBufferUShort(temp ,temp.length);
SampleModel sampleModel = RasterFactory.createBandedSampleModel(
DataBuffer.TYPE_BYTE,
width, height,
1);
WritableRaster myR = RasterFactory.createWritableRaster(sm,dbs,
new Point(0,0));
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
int bits[] = new int[]{16};
ColorModel cm = new ComponentColorModel(cs, bits, false, false,
Transparency.OPAQUE,
DataBuffer.TYPE_USHORT) ;
BufferedImage myBI = new BufferedImage(cm, myR, false,
new Hashtable());
return myBI;

I suspect that the colorModel or sampleModel was not suit for this kind
of grayscale image. The returned image was un-recognizable (brightness
was ok, but I lost 50%-80% contrast). Is there any thing wrong with my
code? Please help.

Thanks in advance
 
A

Andrey Kuznetsov

I am trying to convert a 12 bits grayscale image to BufferedImage from
byte array. But the output image was very poor contrasted. I tried
everything I could think about (by using lut operator, indexColorModel,
etc.) to correct it. There was still no luck for me. The code is shown
below:

short temp[] = new short[width*height];
int index = 0;
try{
byte data[] = new byte[pixelDataLength];
BufferedFileInputStream.read(data);
for( int i =0; i<temp.length;i++){
temp = (short) (data[index++]+((data[index++])<<8));
}
}catch(IOException ex){}

DataBufferUShort dbs= new DataBufferUShort(temp ,temp.length);
SampleModel sampleModel = RasterFactory.createBandedSampleModel(
DataBuffer.TYPE_BYTE,
width, height,
1);
WritableRaster myR = RasterFactory.createWritableRaster(sm,dbs,
new Point(0,0));
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
int bits[] = new int[]{16};
ColorModel cm = new ComponentColorModel(cs, bits, false, false,
Transparency.OPAQUE,
DataBuffer.TYPE_USHORT) ;
BufferedImage myBI = new BufferedImage(cm, myR, false,
new Hashtable());
return myBI;

I suspect that the colorModel or sampleModel was not suit for this kind
of grayscale image. The returned image was un-recognizable (brightness
was ok, but I lost 50%-80% contrast). Is there any thing wrong with my
code? Please help.


the problem is that you use 16 bit ColorSpace with 12 bit data.
you may try to
a) to use 12 bit ColorSpace

b) keep current CS and stretch your data to 16 bit or
a = (a / 16)^2

c) reduce data to 8 bit and use 8 bit CS
a = Math.sqrt(a * 16);

Andrey
 
J

Java_New

Hi Andrey,

Thanks for your reply. I added some code as below, but the output
images still like before. I chose to use the 12 bit ColorSpace:

short temp[] = new short[width*height];
int index = 0;
try{
byte data[] = new byte[pixelDataLength];
BufferedFileInputStream.read(data);
for( int i =0; i<temp.length;i++){
temp = (short) (data[index++]+((data[index++])<<8));
}
}catch(IOException ex){}

DataBufferUShort dbs= new DataBufferUShort(temp, width*height);

byte r[] = new byte[0x1000];
byte g[] = new byte[0x1000];
byte b[] = new byte[0x1000];
int i;
double d = 255.0/4096;
for(i = 0;i < 4096; i++) {
byte b1 = (byte) ((d * i));
r = g = b = (byte)(255-b1) ;
}

IndexColorModel icm = new IndexColorModel(12, 0x1000, r,g,b);

WritableRaster raster =
Raster.createInterleavedRaster(dbs,width,

height, width,

1,new int[]{0},null);
BufferedImage myBI = new BufferedImage(icm, raster, false, new
Hashtable());

Woud you think the code is ok, or I didn't get your idea.

Many thanks
 
A

Andrey Kuznetsov

short temp[] = new short[width*height];
int index = 0;
try{
byte data[] = new byte[pixelDataLength];
BufferedFileInputStream.read(data);

note that InputStream.read(byte [] buffer)
does not guaranteed to fill given buffer,
it returns how much byte was read
So, you have to read in a loop or use readFully(byte [] buffer)

}catch(IOException ex){}
this is really BAD thing, newer swallow exception,
at least make ex.printStackTrace();

for( int i =0; i<temp.length;i++){
temp = (short) (data[index++]+((data[index++])<<8));


BTW are you sure that you are using right byte order?

Andrey
 
J

Java_New

Thanks very much for your help. That was my low level mistake. Every
thing become ok after I change code:
temp = (short) (data[index++]+((data[index++])<<8));

to
temp = (short) (((data[index++])&0xff)+(((data[index++])&0x0F)<<8));

I also appreciate those comments / tips you gave to me.

Thanks
 
A

Andrey Kuznetsov

Thanks very much for your help. That was my low level mistake. Every
thing become ok after I change code:
temp = (short) (data[index++]+((data[index++])<<8));

to
temp = (short) (((data[index++])&0xff)+(((data[index++])&0x0F)<<8));


yes, this is frequent mistake and is difficult to find, I know it too good.

Andrey
 

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

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top