How to capture raw image from android camera

The android (at least mine) has 2 camera parameters "rawsave-mode" and "rawfname", with the default rawsave-mode=0. By setting rawsave-mode=1, the camera will save the raw camera image file, along with performing the other camera functions as usual.

Camera.Parameters parameters=preview.camera.getParameters();
parameters.set("rawsave-mode", "1");
parameters.set("rawfname", "/mnt/sdcard/test.raw");
preview.camera.setParameters(parameters);
preview.camera.takePicture(shutterCallback, null, jpegCallback);

The actual name of the file produced get modified to include the parameters of the raw file being produced. For one of my androids, the name produced is "test__1604x1206_10_2.raw" which is a1 1604x1206 image, 10bit format 2. and "test__1284x966_10_3.raw" which is a 1284×966 image, 10 bit format 3. The 10 bytes are stored as 2 byte short int (little endian).

parameters.set("rawsave-mode", "2");
// setting the rawsave-mode to 2 increased the resolution to 3204x2406
// and output the file test__3204x2406_10_2.raw

The image data is roughly 8 bit, but floats within the 10 bit, where a brighter image might use higher values and darker lower. This allows the image processing software to create a histogram and capture the useful range of the image. Because light is not a constant, it can also be necessary to adjust one channel differently than another to make the image look color correct. There is a lot of info on the web regarding color theory which can explain this fully, but new users beware, the conversion of 10 bit to 8 gets deep quickly. If you want a pretty picture, use the android picture capture and not the raw image!

The format represents the bayer pattern of the bits. Bayer is a format where the odd/even value of the row and column indicate which color the pixel represents, where RGB has an 8 bit value for each color channel for each pixel, bayer has only one 10 bit value for pixel, where one pixel is red, then the next green, red, green, red, green. Then the next row has blue, green, blue, green, blue green. To determine the RGB value of a pixel requires interpreting the surrounding pixels.

Format 2 has pixel order
//            0 1 2 3 4 5
//          0 G R G R G R
//          1 B G B G B G
//          2 G R G R G R
//          3 B G B G B G

format 3 has the pixel order of

//            0 1 2 3 4 5
//          0 R G R G R G
//          1 G B G B G B
//          2 R G R G R G
//          3 G B G B G B

I’m not sure if this technique will work on other androids or if it will work on future androids. If anyone tries this, please add a comment on success or failure. My phones are direct chinese import unlocked iHTC Android phones which have been rooted.

Leave a Comment