C# 从SurfaceView中的摄影机流获取RGB

C# 从SurfaceView中的摄影机流获取RGB,c#,android,xamarin,camera,rgb,C#,Android,Xamarin,Camera,Rgb,我无法从surfaceView获取RGB值。我和C#xamarin一起工作。 尝试使用getBitmap,但此方法不适用于SurfaceView。。 我需要通过触摸surfaceView的某个地方,从摄像机直播流中获取rgb。 也许我需要用别的东西来代替surfaceView? ` public类主活动:活动,ISurfaceHolderCallback,Camera.IPreviewCallback,View.IOnTouchListener { 摄像机(摄像机),; 表面视图(Surface

我无法从surfaceView获取RGB值。我和C#xamarin一起工作。 尝试使用getBitmap,但此方法不适用于SurfaceView。。 我需要通过触摸surfaceView的某个地方,从摄像机直播流中获取rgb。 也许我需要用别的东西来代替surfaceView? `

public类主活动:活动,ISurfaceHolderCallback,Camera.IPreviewCallback,View.IOnTouchListener
{
摄像机(摄像机),;
表面视图(SurfaceView);;
int redValue、blueValue、greenValue;
整数像素;
位图;
TextView _TextView;
创建时受保护的覆盖无效(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
_surfaceview=(surfaceview)FindViewById(Resource.Id.surfaceview W1);
_surfaceview.SetOnTouchListener(此);
var持有人=_surfaceview.holder;
holder.AddCallback(本);
holder.SetType(Android.Views.SurfaceType.PushBuffers);
TabHost TabHost=findviewbyd(Resource.Id.myTab);
Setup();
TabHost.TabSpec tabhost1=TabHost.NewTabSpec(“Tab1”);
tabhost1.SetContent(Resource.Id.tab1);
tabhost1.SetIndicator(“摄像机”);
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);
}
公共bool OnTouch(视图v,运动事件e)
{
开关(电动)
{
案例MotionEventActions.Down:
打破
case MotionEventActions.Up:
pixel=bitmap.GetPixel((int)e.GetX(),(int)e.GetY());
var_color=新颜色(像素);
redValue=\u color.R;
蓝色值=_color.G;
绿色值=_color.B;
_textview.Text=“你好”;
打破
}
返回true;
}
已处理的公共空隙表面(ISurfaceHolder)
{
试一试{
_camera=Android.Hardware.camera.Open();
Android.Hardware.Camera.Parameters p=_Camera.GetParameters();
p、 PictureFormat=Android.Graphics.ImageFormatType.Jpeg;
_摄像机参数设置(p);
_照相机。设置预览回调(此);
_摄像机锁定();
_摄像头。设置显示方向(90);
_摄像头。设置预览显示(支架);
_camera.StartPreview();
}
捕获(System.IO.IOE异常){
}
}
公共空隙表面置换(ISurfaceHolder){
_camera.Unlock();
_camera.review();
_camera.Release();
}
public void surfacechange(ISurfaceHolder,Android.Graphics.Format f,int i,int j)
{
}
void Camera.IPreviewCallback.OnPreviewFrame(字节[]b,Android.Hardware.Camera c)
{
}
}}
`

在预览回调中:

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);
在surfaceChanged中:

setCameraDisplayOrientation((Activity)mContext,0,mCamera);
和SetCameraRadisPlayOrientation(我在CameraPreview类中添加的此方法):

希望这会有所帮助)

在mCurrentImageRGB中,RGB将是此图像的带有RGB整数的整数数组,您可以随意使用它)

我忘了,解码器:

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);
            }
        }
    }
publicstaticvoiddecodeYUV420SP2(int[]rgb,byte[]yuv420sp,int-width,int-height){
最终整数帧大小=宽度*高度;
对于(int j=0,yp=0;j>1)*宽度,u=0,v=0;
对于(int i=0;i262143)
r=262143;
if(g<0)
g=0;
否则,如果(g>262143)
g=262143;
if(b<0)
b=0;
否则,如果(b>262143)
b=262143;
rgb[yp]=0xff000000|((r>2)和0xff00)|((b>>10)和0xff);
}
}
}

您的图像位于字节[]b中,这里有什么问题?使注意力集中的图像大部分是旋转的,因为默认情况下相机会获得横向图像。如果你知道怎么做,我们可以用俄语谈论)我有一个实时相机预览。我需要点击surfaceview,然后在OnTouch action listener中获取点击的像素及其RGB编码检查下面的答案)mCurrentImageRGB-init此变量仅一次)它在Camera2中不起作用,`android.hardware.Camera`已弃用
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);
    }
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);
            }
        }
    }