Camera Preview is getting stretched

2019-03-27 18:06发布

问题:

I have written a code that used to display camera. Following is my layout file's code,

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <FrameLayout
        android:id="@+id/previewLayout"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </FrameLayout>

    <LinearLayout
        android:id="@+id/startBar"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_alignParentRight="true"
        android:background="@drawable/leftbarbg"
        android:orientation="vertical" 
        android:gravity="center">

        <ImageView
            android:id="@+id/MuteBtn"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_weight="2"
            android:src="@drawable/mutebtn" />

        <ImageView
            android:id="@+id/VideosBtn"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_weight="2"
            android:src="@drawable/videosbtn" />

        <ImageView
            android:id="@+id/RecBtn"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_weight="3"
            android:src="@drawable/action_rec_selected" />

        <ImageView
            android:id="@+id/SettingsBtn"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_weight="2"
            android:src="@drawable/settingsbtn" />

        <ImageView
            android:id="@+id/ChatBtn"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_weight="2"
            android:src="@drawable/chatbtn" >
        </ImageView>
    </LinearLayout>

    <RelativeLayout
        android:id="@+id/stopBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="3dp"
        android:visibility="gone" >

        <ImageView
            android:id="@+id/StopBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/stopbtn" />
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="20dp"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="70dp"
        android:layout_marginTop="20dp" >

        <ImageView
            android:id="@+id/MenuBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:src="@drawable/menubtn" />

        <ImageView
            android:id="@+id/LiveModeBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:src="@drawable/livemodeoff" />

        <Chronometer
            android:id="@+id/video_chronometer"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:textSize="28sp"
            android:textStyle="bold" />
    </RelativeLayout>

</RelativeLayout>

And this is my code of CameraSurfaceview,

public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder holder;
    private Camera camera;
    private MediaRecorder mediaRecorder;
    private Boolean previewing;
    private AutoFocusManager autoFocusManager;
    private CameraDetectionObserver cameraDetectionObserver;


    public CameraSurfaceView(Context context, AutoFocusManager autoFocusManager, CameraDetectionObserver cameraDetectionObserver) {
        super(context);
        this.holder = this.getHolder();
        this.holder.addCallback(this);
        this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        this.autoFocusManager= autoFocusManager;
        this.cameraDetectionObserver= cameraDetectionObserver;  
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        if (camera != null) {

            Camera.Parameters parameters = camera.getParameters();
            List< String > FlashModes = parameters.getSupportedFlashModes();
            if (FlashModes.contains(Parameters.FLASH_MODE_AUTO)) {
                parameters.setFlashMode(Parameters.FLASH_MODE_AUTO);
                System.out.println("FLASH_MODE_AUTO");
            }
            List< String > WhiteBalance = parameters.getSupportedWhiteBalance();
            if (WhiteBalance.contains(Parameters.WHITE_BALANCE_AUTO)) {
                parameters.setFlashMode(Parameters.WHITE_BALANCE_AUTO);
                System.out.println("WHITE_BALANCE_AUTO");
            }

            List< String > Antibanding = parameters.getSupportedAntibanding();
            if (Antibanding.contains(Parameters.ANTIBANDING_AUTO)) {
                parameters.setAntibanding(Camera.Parameters.ANTIBANDING_AUTO);
                System.out.println("ANTIBANDING_AUTO");
            }

            List<Size> previews = parameters.getSupportedPreviewSizes();
            int i = 0;

            parameters.setPreviewSize( previews.get(4).width, previews.get(4).height );
            camera.setParameters(parameters);
            camera.startPreview();
            autoFocusManager.startAutoFocus(camera);
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

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

        try {
            camera = Camera.open(findBackFacingCamera());
            camera.setPreviewDisplay(holder);
            previewing = true;
            cameraDetectionObserver.cameraInitializationStatus(true);
        } catch (IOException e) {
            camera.release();
            camera = null;
        }catch (Exception e) {
            e.printStackTrace();
            cameraDetectionObserver.cameraInitializationStatus(false);
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (previewing) {
            camera.stopPreview();
            camera.release();
            camera = null;
            previewing = false;
            autoFocusManager.stopAutoFocus();
            System.out.println("surface destroyed"); 
        }
    }

    public void stopPreview(){
        if (previewing) {
            camera.stopPreview();
            camera.release();
            camera = null; 
            previewing = false;
            autoFocusManager.stopAutoFocus();
            System.out.println("surface destroyed");    
        }
    }

    public Camera getCamera()
    {
        return this.camera;
    }

    public MediaRecorder getMediaRecorder(){
        mediaRecorder = new MediaRecorder();
        camera.unlock();
        mediaRecorder.setCamera(camera);
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
        mediaRecorder.setPreviewDisplay(holder.getSurface());
        mediaRecorder.setVideoFrameRate(29);
        mediaRecorder.setVideoSize(ByteArraysForLogin.VideoDimention.vWidth,ByteArraysForLogin.VideoDimention.vHeight);
        return mediaRecorder;
    }

    private int findBackFacingCamera() {
        int cameraId = -1;
        // Search for the back facing camera
        int numberOfCameras = Camera.getNumberOfCameras();
        for (int i = 0; i < numberOfCameras; i++) {
            CameraInfo info = new CameraInfo();
            Camera.getCameraInfo(i, info);
            if (info.facing == CameraInfo.CAMERA_FACING_BACK) {
                cameraId = i;
                break;
            }
        }
        return cameraId;
    }
}

Above code works fine but it shows camera preview in stretched format in both landscape & portrait mode as following image.

However the resultan camera image is not stretched it is in normal mode only preview is stretched.

P.S. I am asking this question after trying this

回答1:

try adding

getWindow().setFormat(PixelFormat.UNKNOWN);

in your onCreate

if that doesn't help maybe setting the rotation will?

camera.setDisplayOrientation(90);

and if that still doesn't help, all the results on Google are saying the aspect ratio of the SurfaceView must match the aspect ratio of the camera



回答2:

try and use different resolution and increase frame width and height