1

I am opening the android Camera inside a FrameLayout in landscape mode, then the screen looks like-

enter image description here

But the same Image when I open inside ImageView in FrameLayout, then it looks like- enter image description here

Please ignore the content of the Picture and funny squares drawn in the second image. The difference is, First CameraView opened in the entire screen or height touched the head of thescreen but second image shirinking the image to fit.

I want the First image as well work like second, it should fit under a defined rectange. The only objective is Camera View and ImageView shows the same Look.

I can change the entire layout as well if required. FacePreviewImageView is the image I am adding.

First Camera View is Android Camera only and I am adding into the android framelayout-

Camera mCamera = Camera.open(1);
FrameLayout layout = (FrameLayout) findViewById(R.id.ll2);
layout.addView(new CameraView());

Second Frame I am adding like-

layout.removeAllViews();
                layout.addView(faceImageView);
                faceView.setVisibility(View.GONE);
                faceImageView.setVisibility(View.VISIBLE);

The Layout XML is -

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" 
    android:baselineAligned="false">

    <LinearLayout
        android:id="@+id/ll1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" 
        android:orientation="horizontal">


    </LinearLayout>

     <FrameLayout
        android:id="@+id/ll2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="0.5"
        android:orientation="horizontal" >

         <com.example.defaultfacetracker.FacePreviewImageView
             android:id="@+id/facePreview"             
             android:layout_width="match_parent"
             android:layout_height="match_parent" 
             android:src="@android:drawable/toast_frame"
             /> 

    </FrameLayout>

    <LinearLayout
        android:id="@+id/ll3"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:text="Process" />

    </LinearLayout>

</LinearLayout>

My SurfaceHolder looks like-

class Preview extends SurfaceView implements SurfaceHolder.Callback {
    SurfaceHolder mHolder;
    Camera mCamera;
    Camera.PreviewCallback previewCallback;

    Preview(Context context, Camera.PreviewCallback previewCallback, Camera mCamera2) {
        super(context);
        this.previewCallback = previewCallback;
        this.mCamera = mCamera2;

        // 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.
      //  mCamera = Camera.open(1);
        //mCamera.setDisplayOrientation(270);
        try {
           mCamera.setPreviewDisplay(holder);
        } catch (IOException exception) {
            mCamera.release();
            mCamera = null;
            // TODO: add more exception handling logic here
        }
    }

    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.
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }


    private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.05;
        double targetRatio = (double) w / h;
        if (sizes == null) return null;

        Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;

        // Try to find an size match aspect ratio and size
        for (Size size : sizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }

        // Cannot find the one match the aspect ratio, ignore the requirement
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }

    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 = mCamera.getParameters();

        List<Size> sizes = parameters.getSupportedPreviewSizes();
        Size optimalSize = getOptimalPreviewSize(sizes, w, h);
        parameters.setPreviewSize(optimalSize.width, optimalSize.height);

        mCamera.setParameters(parameters);
        if (previewCallback != null) {
            mCamera.setPreviewCallbackWithBuffer(previewCallback);
            Camera.Size size = parameters.getPreviewSize();
            byte[] data = new byte[size.width*size.height*
                    ImageFormat.getBitsPerPixel(parameters.getPreviewFormat())/8];
            mCamera.addCallbackBuffer(data);
        }
//        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
//          mCamera.setDisplayOrientation(90);
//          
//      } else {
//          mCamera.setDisplayOrientation(0);
//      }
        mCamera.startPreview();
    }

}
Abhishek Choudhary
  • 8,255
  • 19
  • 69
  • 128

1 Answers1

4

You set wrong height and width of a camera preview size, also need use setDisplayOrientation, please show code where you set height and width, and set display orientation degrees.

Also you may see properly initialization camera here

artemiygrn
  • 1,036
  • 7
  • 18
  • already shared the piece of code where I set the camera and you can check there is no width and height setting – Abhishek Choudhary Oct 18 '13 at 11:37
  • you have wrong camera init, you need set **camera.setPreviewDisplay(surfaceHolder)**. Where surfaceHolder is holder of SurfaceView, look link above. Or you may look example [here](http://developer.android.com/guide/topics/media/camera.html). Hope it helps. – artemiygrn Oct 18 '13 at 12:08
  • I have updated the question with my SUrface Holder code, where do you find the problem ? – Abhishek Choudhary Oct 18 '13 at 12:18
  • 1
    yes, getOptimalPreviewSize method wrong, better use aspect, again — look code above for example with aspect. – artemiygrn Oct 18 '13 at 12:40
  • Thanks for that now one problem is I am detecting the face , but simple drawing rectangle is very small , i need to do some sort of calculation , what will be that , and still imageView point is not solved , my display image in camera is still coming in the same way as I shown the picture and imageview as well – Abhishek Choudhary Oct 18 '13 at 13:08