Get RGB from a SurfaceView displaying Live camera

android, camera, colors, rgb, surfaceholder

Solution

I thought I could get the data converted from the `SurfaceView`. But the best method to use is :

- Set the camera's orientation to 90 degrees.

- Set output format to NV21 (which is guranteed to be supported on all devices).

- Set to turn the Flash ON.

- Start preview in the `SurfaceView`.

List item

camera = Camera.open();
cameraParam = camera.getParameters();
cameraParam.setPreviewFormat(ImageFormat.NV21);
camera.setDisplayOrientation(90);
camera.setParameters(cameraParam);
cameraParam = camera.getParameters();
camera.setPreviewDisplay(surfaceHolder);
cameraParam.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(cameraParam);
camera.startPreview();

Then, I call the `setPreviewCallback` and `onPreviewFrame` to get the incoming frame, and convert it to RGB pixel array. Which I can then get intensity of each color in the picture by averaging all pixels intensity by running myPixels array through a `for` loop, and checking `Color.red(myPixels[i])` for each desired color (inside the `onPreviewFrame`).

camera.setPreviewCallback(new PreviewCallback() {
    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        int frameHeight = camera.getParameters().getPreviewSize().height;
        int frameWidth = camera.getParameters().getPreviewSize().width;
        // number of pixels//transforms NV21 pixel data into RGB pixels  
        int rgb[] = new int[frameWidth * frameHeight];
        // convertion
        int[] myPixels = decodeYUV420SP(rgb, data, frameWidth, frameHeight);
    }
}

Where `decodeYUV420SP` is found here.

I timed this operation to take about 200ms for each frame. Is there a faster way of doing it?

Problem

I am displaying a live camera in `SurfaceView` using `camera.startPreview();`. Any idea on how I can get live RGB readings from the camera? Thanks

Original source