1

I am trying to set Camera preview in SurfaceView When I set Camera in Surface it looks like stretched preview. How can I solve this?enter image description here

`public class CamActivity extends Activity implements SurfaceHolder.Callback`
`{`
`Camera camera;`
`SurfaceView surface;`
`SurfaceHolder mholder;`
`Button capture;`
`Bitmap bitmap;`
`public  String  path = Environment.getDataDirectory().getAbsolutePath() + "/storage/emulated/0/Pictures/Cam";`
@Override
`protected void onCreate(Bundle savedInstanceState) `
`{`
 `   super.onCreate(savedInstanceState);`
  `  setContentView(R.layout.activity_cam);`
   ` surface=(SurfaceView)findViewById(R.id.camera_view);`
   ` if(mholder==null)`
    `   mholder=surface.getHolder();`
   ` mholder.addCallback(this);`
    `mholder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);`

    `capture=(Button)findViewById(R.id.camera_capture);`
    `File mFolder = new File(path);`
    `if (!mFolder.exists()) {`
     `   mFolder.mkdir();`
    `}`
    `capture.setOnClickListener(new OnClickListener() {`

    `   @SuppressWarnings("deprecation")`
    `   @Override`
    `   public void onClick(View v) {`
    `        camera.takePicture(null, null, new PictureCallback()` 
    `        {`

                @Override
    `           public void onPictureTaken(byte[] data, Camera camera)`
    `           {`

    `               Random generator = new Random();`
    `               int n = 10000;`
    `               n = generator.nextInt(n);`
    `               String fname = "Image-"+ n +".jpg";`
    `               File pictureFile = new File(Environment.getExternalStoragePublicDirectory(`
    `                         Environment.DIRECTORY_PICTURES)+"/", fname);`
    `                try {`
    `                       FileOutputStream fos = new FileOutputStream(pictureFile);`
    `                       bitmap.compress(Bitmap.CompressFormat.JPEG,90, fos);`
    `                       fos.flush();`
    `                       fos.close();`
    `                   } catch (FileNotFoundException e) {`
                            `Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_LONG).show();`
    `                   } catch (IOException e) {`
                            `Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_LONG).show();`
    `                   }`

    `           }`
    `       });`
    `   }`
    `});`
`}`

@Override
`public void surfaceCreated(SurfaceHolder holder) `
`{`
`    camera=Camera.open();`
`    try` 
`    {`
`        camera.setPreviewDisplay(holder);`
`        Toast.makeText(getApplicationContext(), path, Toast.LENGTH_LONG).show();`
`    } `
`    catch (IOException exception)` 
`    {`
`         camera.release();`
`         camera = null;`
`    }`
`}`

@Override
`public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) `
`{`
 `   camera.startPreview();`
  `  camera.setDisplayOrientation(90);`
`}`

@Override
`public void surfaceDestroyed(SurfaceHolder holder)` 
`{
`   camera.stopPreview();`
`    camera.release();`
`    camera = null;`        
`}`
`}`
fadden
  • 51,356
  • 5
  • 116
  • 166
Shaktisinh Jadeja
  • 1,427
  • 1
  • 17
  • 22

1 Answers1

2

You need to listen to orientation change in the activity and set the proper orientation to the camera.

Add this method to your camera activity:

public void setCameraDisplayOrientation(Activity activity) {

    if(null == mCamera){
        return;
     }

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


       if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
           orientation = (info.orientation + degrees) % 360;
           orientation = (360 - orientation) % 360;  // compensate the mirror
       } else {  // back-facing
           orientation = (info.orientation - degrees + 360) % 360;
       }

       if(null != mCamera){
           mCamera.setDisplayOrientation(orientation);
       }
    }

also add OrientationEventListner

    mOrientationEventListener = new OrientationEventListener(mApplication, 
            SensorManager.SENSOR_DELAY_NORMAL) {

        @Override
        public void onOrientationChanged(int orientation) {

            if ((orientation == ORIENTATION_UNKNOWN) || (mCamera == null)) {
                return;
            }

            Camera.Parameters params                = mCamera.getParameters();               
            android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();

            android.hardware.Camera.getCameraInfo(cameraId, info);

            orientation = (orientation + 45) / 90 * 90;

            int rotation = 0;

            if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
                rotation = (info.orientation - orientation + 360) % 360;
            }
            else {  
                /*
                 * back-facing camera
                 */
                rotation = (info.orientation + orientation) % 360;
            }

            params.setRotation(rotation);

            if(null == mCamera) {
                return;
            }

            mCamera.setParameters(params);
        }

    };

Enable orientation listener once the activity starts /* * start orientation listener */
if(mOrientationEventListener.canDetectOrientation()){
mOrientationEventListener.enable(); }

and in the onConfigurationChanged and onResume callback of the activity , make the following call

setCameraDisplayOrientation(Activity activity)

Hope this helps

Regards, Shrish

EDIT UPDATE: Please check out this sample code for camera , most of your doubts should get cleared https://github.com/shrishmv/CameraTest

Shrish
  • 739
  • 5
  • 15
  • How can i get cameraId ? – Shaktisinh Jadeja Nov 24 '14 at 06:05
  • please give me answer – Shaktisinh Jadeja Nov 24 '14 at 09:35
  • 1
    check the github project – Shrish Nov 24 '14 at 16:59
  • 1
    Download and run the sample app from github. It should not give any error. Use it as a reference and modify your code accordingly. Can you tell me what exactly you tried to do ? – Shrish Nov 25 '14 at 11:04
  • I just want to set camera properly in SurfaceView. And the camera screen that displayed in SurfaceView is not stretched – Shaktisinh Jadeja Nov 25 '14 at 11:44
  • 1
    Check these things (use my sample app as reference) 1) set the proper preview size and picture size. ie. first query supported size and set appropriate size 2) set the layout params (height and width) of the camera preivew i.e. surfaceview equal to the preview seize set or a size of the same aspect ratio 3) set the orientation properly , whenever the screen rotates or surfaceview changes 4) If your surfaceview streches beyond the screen/acticity, then set the layout params of the parent to the desired size and then set the surfaceview layout params. All this is done in my sample app. – Shrish Nov 25 '14 at 12:19
  • This really Awesome! Shrish – Phuong Nov 04 '15 at 04:33