简体   繁体   English

相机预览在Android中不全屏

[英]Camera Preview is not FULL SCREEN in android

I am trying to take the camera preview and alter it in onPreviewFrame() and show it to the user. 我正在尝试获取相机预览并在onPreviewFrame()中对其进行更改,并将其显示给用户。 I have already achieved the required functionality but the problem is in SIZE OF CAMERA PREVIEW.It always takes smaller part of the screen and i want to make it fullscreen ie want to take the camera preview which should fill whole screen of the device.I have read and tried any solutions available on net but none of them is working in my case.This is the Surface View class: 我已经实现了所需的功能,但是问题出在相机预览的尺寸上。它总是占据屏幕的较小部分,我想使其全屏显示,即想要拍摄可以覆盖整个设备屏幕的相机预览。阅读并尝试了网络上可用的任何解决方案,但在我的情况下它们都不起作用。这是Surface View类:

public class MySurfaceView extends SurfaceView implements Callback, Camera.PreviewCallback, android.view.SurfaceHolder.Callback {

    private static final String TAG = "MySurfaceView";
    private int width;
    private int height;
    public SurfaceHolder mHolder;
    private Camera mCamera;
    private int[] rgbints;
    private int mMultiplyColor;

    public MySurfaceView(Context context, AttributeSet attrs , Camera camera , 
            int width , int height) 
    {
        super(context, attrs);

        mCamera = camera;

        this.width = width;
        this.height = height;

        mHolder = getHolder();
        mHolder.addCallback(this);

        mMultiplyColor = getResources().getColor(R.color.honeydew);
    }


    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
    {
    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        synchronized (this) {
            this.setWillNotDraw(false); // This allows us to make our own draw calls to this canvas

            rgbints = new int[width * height];

            // try { mCamera.setPreviewDisplay(holder); } catch (IOException e)
            // { Log.e("Camera", "mCamera.setPreviewDisplay(holder);"); }

            mCamera.startPreview();
            mCamera.setPreviewCallback(this);

        }
    }


    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        synchronized (this) {
            try
            {
                CameraActivity cameraActivity = new CameraActivity();
                cameraActivity.releaseCamera();
                cameraActivity = null;
            } catch (Exception e) {
                Log.e("Camera", e.getMessage());
            }
        }
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        Canvas canvas = null;

        if (mHolder == null) 
        {
            return;
        }

        try {
            synchronized (mHolder) 
            {
                canvas = mHolder.lockCanvas(null);

                int canvasWidth = canvas.getWidth();
                int canvasHeight = canvas.getHeight();

                decodeYUV(rgbints, data, width, height);

                // draw the decoded image, centered on canvas
                canvas.drawBitmap(rgbints, 0, width, canvasWidth-((width+canvasWidth)>>1), canvasHeight-((height+canvasHeight)>>1), width, height, false, null);

                // use some color filter
                canvas.drawColor(mMultiplyColor, Mode.MULTIPLY);

            }
        }  catch (Exception e){
            e.printStackTrace();
        } finally {
            // do this in a finally so that if an exception is thrown
            // during the above, we don't leave the Surface in an
            // inconsistent state
            if (canvas != null)
            {
                mHolder.unlockCanvasAndPost(canvas);
                canvas = null;
            }
        }
    }


    public void decodeYUV(int[] out, byte[] fg, int width, int height) throws NullPointerException, IllegalArgumentException {
        int sz = width * height;
        if (out == null)
            throw new NullPointerException("buffer out is null");
        if (out.length < sz)
            throw new IllegalArgumentException("buffer out size " + out.length + " < minimum " + sz);
        if (fg == null)
            throw new NullPointerException("buffer 'fg' is null");
        if (fg.length < sz)
            throw new IllegalArgumentException("buffer fg size " + fg.length + " < minimum " + sz * 3 / 2);
        int i, j;
        int Y, Cr = 0, Cb = 0;
        for (j = 0; j < height; j++) {
            int pixPtr = j * width;
            final int jDiv2 = j >> 1;
        for (i = 0; i < width; i++) {
            Y = fg[pixPtr];
            if (Y < 0)
                Y += 255;
            if ((i & 0x1) != 1) {
                final int cOff = sz + jDiv2 * width + (i >> 1) * 2;
                Cb = fg[cOff];
                if (Cb < 0)
                    Cb += 127;
                else
                    Cb -= 128;
                Cr = fg[cOff + 1];
                if (Cr < 0)
                    Cr += 127;
                else
                    Cr -= 128;
            }
            int R = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5);
            if (R < 0)
                R = 0;
            else if (R > 255)
                R = 255;
            int G = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5);
            if (G < 0)
                G = 0;
            else if (G > 255)
                G = 255;
            int B = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6);
            if (B < 0)
                B = 0;
            else if (B > 255)
                B = 255;
            out[pixPtr++] = 0xff000000 + (B << 16) + (G << 8) + R;
        }
        }

    }

    public void showSupportedCameraFormats(Parameters p) {
        List<Integer> supportedPictureFormats = p.getSupportedPreviewFormats();
        Log.d(TAG, "preview format:" + cameraFormatIntToString(p.getPreviewFormat()));
        for (Integer x : supportedPictureFormats) {
            Log.d(TAG, "suppoterd format: " + cameraFormatIntToString(x.intValue()));
        }

    }

    @SuppressWarnings("deprecation")
    private String cameraFormatIntToString(int format) {
        switch (format) {
        case PixelFormat.JPEG:
            return "JPEG";
        case PixelFormat.YCbCr_420_SP:
            return "NV21";
        case PixelFormat.YCbCr_422_I:
            return "YUY2";
        case PixelFormat.YCbCr_422_SP:
            return "NV16";
        case PixelFormat.RGB_565:
            return "RGB_565";
        default:
            return "Unknown:" + format;

        }
    }
}

This is the caller class: 这是调用方类:

public class CameraActivity extends Activity {

    private Camera mCamera;
    private MySurfaceView surfaceView;
    private RelativeLayout relativeLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        releaseCamera();
    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();

        releaseCamera();
    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();

        mCamera = Camera.open();

        Camera.Parameters p = mCamera.getParameters();
        Size size = p.getPreviewSize();
        int width = size.width;
        int height = size.height;
        p.setPreviewFormat(ImageFormat.JPEG);
        mCamera.setParameters(p);


        surfaceView = new MySurfaceView(this, null , mCamera ,width , height);

        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);

        surfaceView.setLayoutParams(layoutParams);

        relativeLayout = (RelativeLayout)findViewById(R.id.relativeLayout);

        relativeLayout.addView(surfaceView);

        surfaceView.showSupportedCameraFormats(p);
    }

    public void releaseCamera()
    {
        if (mCamera != null)
        {
            mCamera.stopPreview();
            mCamera.setPreviewCallback(null);
            surfaceView.getHolder().removeCallback(surfaceView);
            mCamera.release();        // release the camera for other applications
            mCamera = null;

            surfaceView.mHolder.removeCallback(surfaceView);
            surfaceView.mHolder = null;

            surfaceView = null;

            relativeLayout.removeAllViews();
            relativeLayout.removeAllViewsInLayout();
            relativeLayout = null;
        }

    }
}

Please help me.Thanks in advance. 请帮助我。谢谢。

EDIT: 编辑:

Xml is : Xml是:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:id="@+id/relativeLayout"    
    android:layout_height="match_parent" >

</RelativeLayout>

instend of relativelayout take linearlayout and put framelayout in it: 相对布局的实例采用线性布局,并在其中放置框架布局:

<FrameLayout
            android:id="@+id/preview"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1" >
        </FrameLayout>

and then set camerapreview in it: 然后在其中设置camerapreview:

surfaceView = new MySurfaceView(this, null , mCamera ,width , height);

((FrameLayout) findViewById(R.id.preview)).addView(surfaceView);

CameraPreview.java CameraPreview.java

class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private static final String TAG = "Preview";

    SurfaceHolder mHolder;
    public Camera camera;

    CameraPreview(Context context) {
        super(context);

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, acquire the camera and tell it where
        // to draw.

        if(camera == null){
        camera = Camera.open();


        camera.setDisplayOrientation(90);
        try {
            camera.setPreviewDisplay(holder);


            camera.setPreviewCallback(new PreviewCallback() {

                public void onPreviewFrame(byte[] data, Camera arg1) {

                        CameraPreview.this.invalidate();
                }
            });
        } catch (IOException e) {
           camera.release();
           camera = null;
        }
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // Surface will be destroyed when we return, so stop the preview.
        // Because the CameraDevice object is not a shared resource, it's very
        // important to release it when the activity is paused.
        if(camera!=null){
            camera.stopPreview();
            camera.setPreviewCallback(null);

            camera.release();
            camera = null;
        }

    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // Now that the size is known, set up the camera parameters and begin
        // the preview.
        Camera.Parameters parameters = camera.getParameters();
//        parameters.setPreviewSize(w, h);
        camera.setParameters(parameters);
        camera.startPreview();
    }

    @Override
    public void draw(Canvas canvas) {
            super.draw(canvas);
            Paint p= new Paint(Color.RED);
            Log.d(TAG,"draw");
            canvas.drawText("PREVIEW", canvas.getWidth()/2, canvas.getHeight()/2, p );
    }

    public void releaseCameraAndPreview() {
         if (camera != null) {
            camera.release();
            camera = null;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM