views:

165

answers:

1

Hi everyone!

I need to translate colors in bitmap loaded to BufferedImage from RGB to YCbCr (luminance and 2 channels chrominance) and back after process.

I made it with functions used like rgb2ycbcr() in main method for each pixel, but it isn't so smart solution. I should use ColorSpace and ColorModel classes to get BufferedImage with correct color space. It would be more flexible method, but I don't know how to do that.

I'm lost and I need some tips. Can somebody help me?

A: 

As I understood your question, you want to do the following:

Load RGB image -> process YCbCr image -> Use RGB image again

And you want us to help you, to make this process as seamless as possible. First and foremost you want us to give you a simple way to avoid the -> (converting) parts.

Well I looked into the BufferedImage documentation. It seems, as if there doesn't exist a way to change the ColorSpace of an once created BufferedImage.

You could create a new BufferedImage with an YCbCr color space for that you can use the predefined ICC_ColorSpace. Then you copy the data from your old image possibly via ColorSpace.fromRGB to the YCbCr color space, do the image processing and then convert again via ColorSpace.toRGB. This method requires you to fully convert the image before and after processing via existing methods. Furthermore you have to know, how ICC_ColorSpace converts your image to YCbCr color space. Otherwise you can't know, which array indices corresponds to the same pixel.

If you just want to create a wrapper around the RGB-BufferedImage that lets you manipulate this image, as if it was an YCbCr image, that isn't possible with BufferedImage.

EDIT: To convert the color space of a BufferedImage use ColorConvertOp. The code would look something like this:

ColorConvertOp cco = new ColorConvertOp(new YCbCrColorSpace(), null);
BufferedImage ycbcrImage = cco.filter( oldRGBImage, null );

This requires you to either write your own ColorSpace class or you could download and use the classes mentioned here. If you just want to load a JPEG image you should use the predefined classes.

ablaeul
But I still don't know how to do that. I'm lost and I can find anything above documentation of classes. This is so different from static functions. Any examples?I'm writing implementation of JPEG algorithm and I need to convert to YCbCr and separate channels before fragmentation. Now I'm working with many arrays and function. This is not so flexible as I want.
Onlyx
Maybe the `BufferedImage` class is not what you're looking for. If you just want your procedural Jpeg (de-)encoder to make more OOP-like try something else. One possibility is to make a class for every step of the Jpeg (de-)encodeing pipeline.
ablaeul
Ok. From the beginning :)I need to open image, separate Y, Cb, Cr channels and fragment each channel before compression.So I need BufferedImage with getY(), getCb, getCr() methods or three with one channel for each. How to do that?
Onlyx
Don't use `BufferedImage` for that. Either you write your own class doing what you want or use [`WritableRaster`][1] use the documentation of [`Raster`][2] to see, how the pixels are stored. Because this discussion to this answer gets ridiculously long, this will be my last comment here. [1]: http://java.sun.com/javase/6/docs/api/java/awt/image/WritableRaster.html [2]: http://java.sun.com/javase/6/docs/api/java/awt/image/Raster.html
ablaeul