Search code examples
javac#.netimage-processingbufferedimage

Convert RAW image into jpg in java


I have capturing device which is returning RAW 640x480 BGR. The docs to support it have only .net/C# code samples.

Here is a sample code they have in the .net SDK

Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0,
                                                            bmp.Width,
                                                            bmp.Height),
                                              ImageLockMode.WriteOnly,
                                              bmp.PixelFormat);

Marshal.Copy(faceImage, 0, bmpData.Scan0, faceImage.Length);
bmp.UnlockBits(bmpData);

Here is the closest I got in Java but colors are still off

int nindex = 0;
int npad = (raw.length / nHeight) - nWidth * 3;

BufferedImage bufferedImage = new BufferedImage(nWidth, nHeight, BufferedImage.TYPE_4BYTE_ABGR);
DataBufferByte dataBufferByte = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer());
byte[][] bankData = dataBufferByte.getBankData();
byte brgb[] = new byte[(nWidth + npad) * 3 * nHeight];

System.arraycopy(raw, 0, brgb, 0, raw.length);

for(int j = 0; j < nHeight - 1; j++)
{
    for(int i = 0; i < nWidth; i++)
    {
        int base = (j * nWidth + i) * 4;
        bankData[0][base] = (byte) 255;
        bankData[0][base + 1] = brgb[nindex + 1];
        bankData[0][base + 2] = brgb[nindex + 2];
        bankData[0][base + 3] = brgb[nindex];
        nindex += 3;
    }
    nindex += npad;
}

ImageIO.write(bufferedImage, "png", bs);

The red and green colors seems to be inverted. Appreciate your feedback to get this fixed. Thank you!


Solution

  • The following part of your code seems not quite right to me

    bankData[0][base] = (byte) 255;
    bankData[0][base + 1] = brgb[nindex + 1];
    bankData[0][base + 2] = brgb[nindex + 2];
    bankData[0][base + 3] = brgb[nindex];
    

    You are defining your buffered image with TYPE_4BYTE_ABGR. The Java docs say

    The byte data is interleaved in a single byte array in the order A, B, G, R from lower to higher byte addresses within each pixel.

    According to you, the format of the raw image should be BGR, too, hence the bytes in your raw image should have the order B, G, R from lowest, to highest byte, right? As far as I can tell from your snippet, you are copying Red channel value to Green channel, Blue channel value to Red channel and Green channel value to Blue channel. Copying the bytes shoud be rather

    bankData[0][base] = (byte) 255;
    bankData[0][base + 1] = brgb[nindex]; // B
    bankData[0][base + 2] = brgb[nindex + 1]; // G
    bankData[0][base + 3] = brgb[nindex + 2]; // R