Reducing Color depth of an image in java

I have a necissity where I need to transmit images from one machine to other. These images are typically Screen Shots. In java using robot I am getting a 32 bit color depth images. I need to reduce their size and color depth. currently I am converting screen shots to jpg and png, but in order to reduce the size further I need to reduce the color depth.

Can any body tell me a way where I can reduce the color depth of an image in java ?
LVL 2
ThummalaRaghuveerAsked:
Who is Participating?
 
objectsConnect With a Mentor Commented:
If you wanted to have a play with a different png encoder in the meantime, then you could try this:
http://catcode.com/pngencoder/
0
 
CEHJCommented:
It's possible, i think, to do this without advanced libraries, but would be probably much easier with them:

http://jiu.sourceforge.net/
0
 
TimYatesConnect With a Mentor Commented:
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
ThummalaRaghuveerAuthor Commented:
http://www.gurge.com/amd/java/quantize/

I think quantize code in this link is not actually reducing the image, but is just playing around with the same image and trying to change the pixel colors in an appropriate way. I checked the sizes of various variables in the code and they never seem to change with what ever the level of compression. They are remaing the same as the original image.
0
 
ThummalaRaghuveerAuthor Commented:
With the code available at
http://jiu.sourceforge.net/
is actually increasing my image sizes. I tried their example code on an image of size 72 kb and its size after conversion came to 339 kb in grey scale. Also it does not have anything to do with the jpg formats. I want to reduce the color depth because I wanted to reduce the size of the image... can anybody send a piece of code that does it or direct to a link which does it. Currently my images are of size 128 x 128 pixels and their size is from 250 bytes to 5kB. I want to reduce these sizes by reducing the color depth of the image.
0
 
objectsCommented:
theres example code in the links i posted above.
0
 
CEHJCommented:
Color reduction is not trivial, which is probably why you are having trouble finding something. See http://community.borland.com/article/0,1410,15972,00.html
0
 
TimYatesCommented:
> I checked the sizes of various variables in the code and they never seem to change with what ever the level of compression. They are remaing the same as the original image.

But if you quantise the image down to say 8 colors, then jpeg compress the image with a high compression, the image size *should* be smaller

Don't forget that if you are sending the image as a jpg, it *has* to be a 32bit image...  That is what JPG is...
0
 
objectsCommented:
Thats right, check exactly what your encoder is doing with the colour depth.
0
 
CEHJCommented:
Don't forget that the png's compression capabilities are probably not being used. Can you post a link to one?
0
 
ThummalaRaghuveerAuthor Commented:
This is what I am doing currently..
//Here bi is the buffered image of the image I am trying to send.
ByteArrayOutputStream out = new ByteArrayOutputStream();
            ByteArrayOutputStream out1 = new ByteArrayOutputStream();
            try {
                  ImageIO.write(bi, "jpg", out);
                  ImageIO.write(bi, "png", out1);
                  byte[] jpg = out.toByteArray();
                  byte[] png = out.toByteArray();
                  if (jpg.length < png.length) {
                        return jpg;
                  } else {
                        return png;
                  }

The bi here is of 32 bit color depth

At the receiving end I do the following once I store this byte array of jpg or png.

//Here the bytes in jpg or png are stored in imageBytes
BufferedImage newImage = ImageIO.read(new ByteArrayInputStream(imageBytes));

Here in quantize they are creating instance of Image from MemoryImageSource

How to get a jpg or png using an instance of Image or MemoryImageSource??

Thanks
0
 
objectsCommented:
you want to be reducing the depth before you send it over the wire don'ty you?
How you decode it seems irrelevant.
0
 
ThummalaRaghuveerAuthor Commented:
Yaa I wish to do that but currently I am not doing it. I just generating a jpg or png and then seding it over the wire...

At the other end all I am doing is recreating the BufferedImage from the jpg or png image information stored in an array....

As of now I am not reducing the color depth.....
0
 
objectsCommented:
So what is it exactly you want to do?
0
 
ThummalaRaghuveerAuthor Commented:
Either process jpg/png that is generated and reduce the color depth of the image

or

process the bufferedImage and alter it in a way so that the jpg or png that I would get finally has a reduced color depth
0
 
CEHJCommented:
You'd probably find it easier to get a library that supports png compression
0
 
ThummalaRaghuveerAuthor Commented:
does the png compression libraries reduce the color depth and also the size of the resulting image.. If so where can I find one and also a way to use it...?
0
 
objectsCommented:
No it doesn't.
0
 
CEHJCommented:
>>does the png compression libraries reduce the color depth

No

>>and also the size of the resulting image

If you mean file size, then yes

0
 
ThummalaRaghuveerAuthor Commented:
I am already compressing the images into png using

ImageIO.write(bi, "png", out1);

as I mentioned above.....

I want to reduce file size further by reducing the quality of the image
0
 
CEHJCommented:
>>I am already compressing the images into png using ...

That won't compress them
0
 
objectsCommented:
> I want to reduce file size further by reducing the quality of the image

Yes I realise that, will see if I can get something for you.
0
 
CEHJCommented:
As i mentioned before, please post a link to one of these pngs
0
 
objectsCommented:
(s)he's already using compression, its the colour depth that needs to be reduced.

Did you have any particular mapping you wanted to use to reduce the color depth?
0
 
CEHJCommented:
>>(s)he's already using compression

How? Java doesn't support png compression (last i looked anyway)
0
 
CEHJCommented:
Personally, i think the likelihood of your finding a Java library to reduce color depth that doesn't trash the image somewhat slim
0
 
ThummalaRaghuveerAuthor Commented:
Nope I do not have any mappings to reduce the color depth..

The application does not store anything in files it just pushes them over the wire.... I`ll modify it to write into files and then post link to those images
0
 
objectsCommented:
copies of the images aren't really necessary as you've explained how they are produced.
the colour reduction needs to be done before the encoding so how they are encoded is not really relevant.
Will see if I can find some time to put some code together for you.
0
 
CEHJCommented:
>>... so how they are encoded is not really relevant.

>>If you wanted to have a play with a different png encoder in the meantime, then you could try this

LOL
0
 
ThummalaRaghuveerAuthor Commented:
Anyway if you want to have a copy of the image created I have created You can access them at
http://www.cs.odu.edu/~rthummal/image/

I`ll keep looking into the encoders you have mentioned

Thanks...
0
 
ThummalaRaghuveerAuthor Commented:
Finally Things started working...

but the way its beeing done is funny and is not efficient... Its some thing like creating a jpg or png as described in previous code and then alter it and create a png again.... If I could do this directly it would be great.... Here is how I did it......

Once I create a jpg or png as described in above code.... I am sending it to quantize program which plays around with the pixels and decreases the number of colors shown... Then I altered setImage(int,int,int[]) method in ImageFrame of quantize to use pngEncoder and compress it with a factor of 9 and make it return the image...

I am sending this image over the wire.......

Can we do the what quantize does directly using a BufferredImage instead of a jpg or png...?
0
 
CEHJConnect With a Mentor Commented:
>>Can we do the what quantize does directly using a BufferredImage instead of a jpg or png...?

call the code in TestQuantize.main at http://www.gurge.com/amd/java/quantize/src/TestQuantize.java
0
 
ThummalaRaghuveerAuthor Commented:
I think I cannot call PixelGrabber on a bufferedImage
0
 
CEHJCommented:
Yes, you can
0
 
objectsCommented:
I should have a standalone routine done for you in the next couple of days, just a bit busy with other work at the moment. Will let you know.
0
 
ThummalaRaghuveerAuthor Commented:
Can U give an Idea How......

In pixelGrabber I did not see any methods that operate on BufferedImage
0
 
objectsCommented:
BufferedImage is a subclass of Image so it can be used.
0
 
ThummalaRaghuveerAuthor Commented:
Thankyou very much for Ur help in this
0
 
CEHJCommented:
:-)
0
 
objectsCommented:
no worries, glad I could help (:
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.