从 SurfaceView 中的相机流中获取 RGB



我无法从surfaceView获取RGB值。我正在使用 xamarin,C#。尝试使用getBitmap,但此方法不适用于SurfaceView。我需要通过触摸 surfaceView 上的某个地方从摄像机实时流中获取 rgb。也许我需要使用其他东西而不是表面视图?`

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)
        {
        }
    }}

'

in 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);

在相机预览中:

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

在表面更改:

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);
            }
        }
    }

最新更新