从SurfaceView中的相机流中获取RGB

时间:2016-05-29 21:37:56

标签: c# android xamarin camera rgb

我无法从surfaceView获取RGB值。我正在使用xamarin,C#。 试图使用getBitmap,但这种方法不适用于SurfaceView .. 我需要通过触摸surfaceView的某个地方从相机直播中获取rgb。 也许我需要使用其他东西而不是surfaceView? `

public class MainActivity : Activity, ISurfaceHolderCallback, Camera.IPreviewCallback, View.IOnTouchListener
    {
Camera _camera;
        SurfaceView _surfaceview;
        int redValue,blueValue,greenValue;
        int pixel;  
        Bitmap bitmap;
        TextView _textview;


        protected override void OnCreate (Bundle savedInstanceState)
        {
            base.OnCreate (savedInstanceState);
            SetContentView (Resource.Layout.Main);
            _surfaceview = (SurfaceView)FindViewById (Resource.Id.surfaceView1);
            _surfaceview.SetOnTouchListener (this);
            var holder = _surfaceview.Holder;
            holder.AddCallback (this);
            holder.SetType (Android.Views.SurfaceType.PushBuffers);


            TabHost tabhost = FindViewById<TabHost> (Resource.Id.myTab);

            tabhost.Setup ();

            TabHost.TabSpec tabhost1 = tabhost.NewTabSpec ("Tab1");
            tabhost1.SetContent (Resource.Id.tab1);
            tabhost1.SetIndicator ("CAMERA");
            tabhost.AddTab (tabhost1);

            TabHost.TabSpec tabhost2 = tabhost.NewTabSpec ("Tab2");
            tabhost2.SetContent (Resource.Id.tab2);
            tabhost2.SetIndicator ("RGB");
            tabhost.AddTab (tabhost2);

            _textview = (TextView)FindViewById (Resource.Id.textView1);

        }

        public bool OnTouch(View v, MotionEvent e)
        {
            switch (e.Action)
            {
            case MotionEventActions.Down:
                break;
            case MotionEventActions.Up:
                pixel = bitmap.GetPixel ((int)e.GetX (), (int)e.GetY ());
                var _color = new Color (pixel);
                redValue = _color.R;
                blueValue = _color.G;
                greenValue = _color.B;
                _textview.Text = "Hello";
                break;
            }
            return true;
        }

        public void SurfaceCreated(ISurfaceHolder holder)
        {
            try{
                _camera = Android.Hardware.Camera.Open();
                Android.Hardware.Camera.Parameters p = _camera.GetParameters();
                p.PictureFormat = Android.Graphics.ImageFormatType.Jpeg;
                _camera.SetParameters(p);
                _camera.SetPreviewCallback(this);
                _camera.Lock();

                _camera.SetDisplayOrientation(90);
                _camera.SetPreviewDisplay(holder);
                _camera.StartPreview();

            }
            catch(System.IO.IOException e){
            }
        }

        public void SurfaceDestroyed(ISurfaceHolder holder){

            _camera.Unlock ();
            _camera.StopPreview ();
            _camera.Release ();
        }

        public void SurfaceChanged(ISurfaceHolder holder,Android.Graphics.Format f,int i, int j)
        {
        }

        void Camera.IPreviewCallback.OnPreviewFrame(byte[] b, Android.Hardware.Camera c)
        {
        }

    }}

`

1 个答案:

答案 0 :(得分:0)

在PreviewCallBack中

Camera.Parameters parameters = camera.getParameters();
            Camera.Size size = parameters.getPreviewSize();
            Camera.CameraInfo info = new Camera.CameraInfo();
            Camera.getCameraInfo(0, info);
            if(mBitmapWidth == 0 || mBitmapHeight == 0) {
                mBitmapWidth = size.width;
                mBitmapHeight = size.height;
            }

            mCurrentImageRGB = new int[mBitmapWidth*mBitmapHeight];
            Recognize.decodeYUV420SP2(mCurrentImageRGB, data, mBitmapWidth, mBitmapHeight);

在CameraPreview中:

mCamera.getParameters().setPreviewFormat(ImageFormat.NV21);

在surfaceChanged中:

setCameraDisplayOrientation((Activity)mContext,0,mCamera);

和setCameraDisplayOrientation(我在CameraPreview类中添加了这个方法):

public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) {
        android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(cameraId, info);
        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360; 
        } else { 
            result = (info.orientation - degrees + 360) % 360;
        }

        camera.setDisplayOrientation(result);
    }

希望这会有所帮助)

mCurrentImageRGB中的

将是这个图像的RGB整数的int数组,无论你想要什么,你都可以使用它们。

int middlePixel = mCurrentImageRGB[mBitmapWidth/2 + mBitmapHeight/2]; // this is your rgb pixel somewhere in center of image :)

我忘了,解码器:

public static void decodeYUV420SP2(int[] rgb, byte[] yuv420sp, int width, int height) {

        final int frameSize = width * height;

        for (int j = 0, yp = 0; j < height; j++) {
            int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
            for (int i = 0; i < width; i++, yp++) {
                int y = (0xff & ((int) yuv420sp[yp])) - 16;
                if (y < 0)
                    y = 0;
                if ((i & 1) == 0) {
                    v = (0xff & yuv420sp[uvp++]) - 128;
                    u = (0xff & yuv420sp[uvp++]) - 128;
                }

                int y1192 = 1192 * y;
                int r = (y1192 + 1634 * v);
                int g = (y1192 - 833 * v - 400 * u);
                int b = (y1192 + 2066 * u);

                if (r < 0)
                    r = 0;
                else if (r > 262143)
                    r = 262143;
                if (g < 0)
                    g = 0;
                else if (g > 262143)
                    g = 262143;
                if (b < 0)
                    b = 0;
                else if (b > 262143)
                    b = 262143;
                rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
            }
        }
    }