Rahul Raj
Rahul Raj

Reputation: 367

How to get the Camerapreview data in monodroid

Can anyone please help me in getting the camerapreview frame data without clicking the camara click. I want to get the currect camera data with out clicking the camera button

Upvotes: 2

Views: 1173

Answers (3)

Bob Powell
Bob Powell

Reputation: 146

Seeing as you're using MonoDevelop and not writing in Java the procedure will be a little different.

You can create a camera preview handler class like so:

public class CameraListener : Java.Lang.Object, Camera.IPreviewCallback
{
    public event PreviewFrameHandler PreviewFrame;

    public void OnPreviewFrame(byte[] data, Camera camera)
    {
        if (PreviewFrame != null)
        {
            PreviewFrame(this, new PreviewFrameEventArgs(data, camera));
        }
    }
}

public delegate void PreviewFrameHandler(object sender, PreviewFrameEventArgs e);

public class PreviewFrameEventArgs : EventArgs
{
    readonly byte[] _data;
    readonly Camera _camera;

    public byte[] Data { get { return _data; } }

    public Camera Camera { get { return _camera; } }

    public PreviewFrameEventArgs(byte[] data, Camera camera)
    {
        _data = data;
        _camera = camera;
    }
}

The class provides an event that is fired for each frame received.

In my own code I use the YUV420_NV21 format

I decode the data using the following method:

        unsafe public static void convertYUV420_NV21toRGB565(byte* yuvIn, Int16* rgbOut, int width, int height, bool monochrome)
    {
        int size = width * height;
        int offset = size;
        int u, v, y1, y2, y3, y4;

        for (int i = 0, k = 0; i < size; i += 2, k += 2)
        {
            y1 = yuvIn[i];
            y2 = yuvIn[i + 1];
            y3 = yuvIn[width + i];
            y4 = yuvIn[width + i + 1];

            u = yuvIn[offset + k];
            v = yuvIn[offset + k + 1];
            u = u - 128;
            v = v - 128;

            if (monochrome)
            {
                convertYUVtoRGB565Monochrome(y1, u, v, rgbOut, i);
                convertYUVtoRGB565Monochrome(y2, u, v, rgbOut, (i + 1));
                convertYUVtoRGB565Monochrome(y3, u, v, rgbOut, (width + i));
                convertYUVtoRGB565Monochrome(y4, u, v, rgbOut, (width + i + 1));
            }
            else
            {
                convertYUVtoRGB565(y1, u, v, rgbOut, i);
                convertYUVtoRGB565(y2, u, v, rgbOut, (i + 1));
                convertYUVtoRGB565(y3, u, v, rgbOut, (width + i));
                convertYUVtoRGB565(y4, u, v, rgbOut, (width + i + 1));
            }

            if (i != 0 && (i + 2) % width == 0)
                i += width;
        }
    }

    unsafe private static void convertYUVtoRGB565Monochrome(int y, int u, int v, Int16* rgbOut, int index)
    {
        rgbOut[index] = (short)(((y & 0xf8) << 8) |
                      ((y & 0xfc) << 3) |
                      ((y >> 3) & 0x1f));
    }

    unsafe private static void convertYUVtoRGB565(int y, int u, int v, Int16* rgbOut, int index)
    {
        int r = y + (int)1.402f * v;
        int g = y - (int)(0.344f * u + 0.714f * v);
        int b = y + (int)1.772f * u;
        r = r > 255 ? 255 : r < 0 ? 0 : r;
        g = g > 255 ? 255 : g < 0 ? 0 : g;
        b = b > 255 ? 255 : b < 0 ? 0 : b;
        rgbOut[index] = (short)(((b & 0xf8) << 8) |
                      ((g & 0xfc) << 3) |
                      ((r >> 3) & 0x1f));
    }

I've included both monochrome and colour decoders.

The resulting data from this code is in the OpenGL 565 RGB format and can be used to initialise OpenGL textures or you can just mess with the pixels for image analysis etc.

Bob Powell.

Upvotes: 3

Greg Shackles
Greg Shackles

Reputation: 10139

This recipe from Xamarin explains how to use the Camera class to get a preview and display it to the user.

Upvotes: 1

anayman
anayman

Reputation: 111

I guess you are searching for this function in the Camera class,

   public final void setPreviewCallback (Camera.PreviewCallback cb)

Define the callback

private PreviewCallback mPreviewCallback = new PreviewCallback() {
      public void onPreviewFrame(byte[] data, Camera camera) {
     }
}

Once the preview is started this callback will get triggered on each frame, the data (byte[]) are in the preview format, which you can find while setting the Camera Parameters

First get a list of supported preview formats

List<Integer> Camera.Parameters.getSupportedPreviewFormats()

the default format is ImageFormat.NV21

If you want to change the preview format use this function, choose a format from the available formats

Camera.Parameters.setPreviewFormat(int pixel_format)

Upvotes: 3

Related Questions