Dmitry
Dmitry

Reputation: 41

How to set XYZ-ColorSpace pixel in BufferedImage?

private BufferedImage outputImg;

for(int y = 0; y < inputImg.getHeight(); ++y)
{
    for(int x = 0; x < inputImg.getWidth(); ++x)
    {
        Color originPixel = new Color(inputImg.getRGB(x, y));
        double X = 0.412453 * originPixel.getRed() + 0.35758 * originPixel.getGreen() + 0.180423 * originPixel.getBlue();
        double Y = 0.212671 * originPixel.getRed() + 0.71516 * originPixel.getGreen() + 0.072169 * originPixel.getBlue();
        double Z = 0.019334 * originPixel.getRed() + 0.119193 * originPixel.getGreen() + 0.950227 * originPixel.getBlue();
        //???
    }
}

In color space conversion function I get RGB-pixel and convert it into XYZ-pixel. But how to set this result in outputImg?
Among BufferedImage methods I see only setRGB(int r, int g, int b)

Upvotes: 1

Views: 471

Answers (1)

Harald K
Harald K

Reputation: 27054

To work with a BufferedImage in a different color model than RGB, you typically have to work with the Raster or DataBuffer directly.

The fastest way to convert from an RGB color space (like sRGB) to an XYZ color space (like CIEXYZ), is to use ColorConvertOp. However, I assume that this is an assignment, and your task is to implement this yourself.

It's possible to create an XYZ BufferedImage like this:

int w = 1024, h = 1024; // or whatever you prefer

ColorSpace xyzCS = ColorSpace.getInstance(ColorSpace.CS_CIEXYZ);
ComponentColorModel cm = new ComponentColorModel(xyzCS, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
WritableRaster raster = cm.createCompatibleWritableRaster(w, h);
BufferedImage xyzImage = new BufferedImage(cm, raster, cm.isAlphaPremultiplied(), null);

You can then modify the samples/pixels through the WritableRaster, using raster.setPixel(x, y, pixelData) or raster.setPixels(x, y, w, h, pixelData) or one of the raster.setSample(x, y, band, ...)/setSamples(x, y, w, h, band, ...) methods.

You can also get the DataBuffer, using raster.getDataBuffer(), or if you really like to, access the backing array directly:

// The cast is safe, as long as you used DataBuffer.TYPE_BYTE for cm above
DataBufferByte buffer = (DataBufferByte) raster.getDataBuffer();
byte[] pixels = buffer.getData();

Upvotes: 1

Related Questions