androidandroid-camerasurfaceviewgrafika

Grafika's CameraCaptureActivity - camera preview distorted on preview size change


I referred to Grafika's CameraCaptureActivity to record video while simultaneously displaying the camera preview.

The changes I have made to the code (that is relevant) is -

The user clicks a button to launch PreferencesActivity, selects the preferred camera resolution (which stores the width and height values) and clicks the "Back" button to return to the CameraCaptureActivity.

In the openCamera method- Instead of hard coding width and height I am picking the values from SharedPreferences

The AspectFrameLayout's attribute is set this way android:background="@android:color/holo_blue_bright". So the preview is matching the size of the AspectFrameLayout

This problem occurs mostly when the size is being changed from a bigger resolution to a smaller one.

In smaller screens (HTC One M7 / Xperia SP) Distorted camera preview in HTC

In larger screens (Samsung Galaxy Tab S / Nexus 9) - Distorted camera preview in Samsung Tab S

I have noticed that this happens because onSurfaceChanged gets called twice. The first time it is with wrong values for width and height and the second time it is with the correct values.

However, the layout looks fine if I leave the activity and come back to it without making any changes. (Like going to PreferencesActivity and clicking "Back" without changing the resolution.)

I have set the following in AndroidManifest.xml -

<activity android:name=".activity.camera.CameraCaptureActivity"
 android:launchMode="singleInstance"
 android:screenOrientation="landscape"
 android:theme="@android:style/Theme.Holo.Light.NoActionBar">
</activity>

EDIT: This issue occurs with only the preview. The recorded video is sized correctly.

EDIT 2: This is my layout.xml

    <RelativeLayout xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cameracapturescreen_rootparent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
tools:context="com.myapp.CameraCaptureActivity">

<com.myapp.activity.camera.PreviewFrameLayout
    android:id="@+id/surfaceview_framelayout"
    android:layout_width="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_centerVertical="true"
    android:background="@android:color/holo_blue_bright"
    android:layout_height="wrap_content">

    <android.opengl.GLSurfaceView
        android:id="@+id/cameraPreview_surfaceView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="left"/>

</com.myapp.activity.camera.PreviewFrameLayout>

I am sure I am passing the correct values to set the width and height of the view because the preview is set correctly if I leave the activity and come back to it without making any changes. (Like going to another activity and clicking "Back" to return to CameraCaptureActivity.)


Solution

  • I am not clear with what you are trying to say if the problem is with the preview .. then you can use the following code in your open camera method

    add this thing code in your openCamera() method , i just checked with this ... hope this helps

        if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
            mCamera.setDisplayOrientation(90);
        } else {
            mCamera.setDisplayOrientation(180);
        }
    

    Add this code in your handleSetSurfaceTexture() method

        if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
            mCamera.setDisplayOrientation(90);
         } else {
            mCamera.setDisplayOrientation(180);
        }
              Camera.Parameters parms = mCamera.getParameters();
    
              CameraUtils.choosePreviewSize(parms, mCameraPreviewWidth, mCameraPreviewHeight);
    
              // Give the camera a hint that we're recording video.  This   can have a big
              // impact on frame rate.
              parms.setRecordingHint(true);
              mCamera.setParameters(parms);
    

    and this part of code in your onPause()

    InputMethodManager imm = (InputMethodManager)getSystemService(
    Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(((EditText)findViewById(R.id.username)).getWindowToken(), 0);
    
    if(imm.isAcceptingText()) {
    Intent intent = new Intent(this, CameraCaptureActivity.class);
    startActivity(intent);
    }