Camera preview bar for Android

Please help to set up Android camera configuration (tested on HTC Desire 2.3.3) for camera preview in rotation (portrait) mode. The preview takes up less than half of the screen, must be as wide as the device, and scaled dynamically to match the aspect ratio of the camera. My current code:

public class CameraSurface extends SurfaceView implements SurfaceHolder.Callback {
public void surfaceCreated(SurfaceHolder holder) {
try {
    if (camera != null) {
                try {
                    camera.stopPreview();
                } catch (Exception ignore) {
                }
                try {
                    camera.release();
                } catch (Exception ignore) {
                }
                camera = null;
            }

            camera = Camera.open();             
            camera.setPreviewDisplay(holder);
        } catch (Exception ex) {
            try {
                if (camera != null) {
                    try {
                        camera.stopPreview();
                    } catch (Exception ignore) {
                    }
                    try {
                        camera.release();
                    } catch (Exception ignore) {
                    }
                    camera = null;
                }
            } catch (Exception ignore) {    
            }
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        try {
            if (camera != null) {
                try {
                    camera.stopPreview();
                } catch (Exception ignore) {
                }
                try {
                    camera.release();
                } catch (Exception ignore) {
                }
                camera = null;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }


    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        try {
            Camera.Parameters parameters = camera.getParameters();
            float bff = 0;
            try {
                List<Camera.Size> supportedSizes = null;

                //maximize supported resizes, TODO remove as hardcode
                w*=1.5;
                h*=1.5;

                // On older devices (<1.6) the following will fail
                // the camera will work nevertheless
                supportedSizes = Compatibility.getSupportedPreviewSizes(parameters);

                // preview form factor
                float ff = (float) w / h;
                Log.d("TAG", "Screen res: w:" + w + " h:" + h
                        + " aspect ratio:" + ff);

                // holder for the best form factor and size                 
                int bestw = 0;
                int besth = 0;
                Iterator<Camera.Size> itr = supportedSizes.iterator();

                // we look for the best preview size, it has to be the closest
                // to the
                // screen form factor

                while (itr.hasNext()) {
                    Camera.Size element = itr.next();
                    // current form factor
                    float cff = (float) element.width / element.height;
                    // check if the current element is a candidate to replace
                    // the best match so far
                    // current form factor should be closer to the bff
                    // preview width should be less than screen width
                    // preview width should be more than current bestw
                    // this combination will ensure that the highest resolution
                    // will win
                    Log.d("TAG", "Candidate camera element: w:"
                            + element.width + " h:" + element.height
                            + " aspect ratio:" + cff);
                    if ((ff - cff <= ff - bff) && (element.width <= w)
                            && (element.width >= bestw)) {
                        bff = cff;
                        bestw = element.width;
                        besth = element.height;
                    }
                }
                Log.d("TAG", "Chosen camera element: w:" + bestw + " h:"
                        + besth + " aspect ratio:" + bff);
                // Some Samsung phones will end up with bestw and besth = 0
                // because their minimum preview size is bigger then the screen
                // size.
                // In this case, we use the default values: 480x320
                if ((bestw == 0) || (besth == 0)) {
                    Log.d("Mixare", "Using default camera parameters!");
                    bestw = 480;
                    besth = 320;
                }               
                parameters.setPreviewSize(bestw,besth);
            } catch (Exception ex) {
                parameters.setPreviewSize(480,320);

                bff=1.5f;
            }
            makeResizeForCameraAspect(bff);                     
            camera.setDisplayOrientation(90);//only Android 2.2 and later
            camera.setParameters(parameters);               
            camera.startPreview();
        } catch (Exception ex) {
            Log.e(TAG,"",ex);
        }
    }

    private void makeResizeForCameraAspect(float cameraAspectRatio){
        LayoutParams layoutParams=this.getLayoutParams();
        int matchParentWidth=this.getWidth();           
        int newHeight=(int)(matchParentWidth/cameraAspectRatio);
        if(newHeight!=layoutParams.height){
            layoutParams.height=newHeight;
            layoutParams.width=matchParentWidth;    
            this.setLayoutParams(layoutParams);
            this.invalidate();
        }
    }
}

      

Scheme of actions:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >  
    <org.mixare.CameraSurface
        android:id="@+id/camera_surface"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:layout_alignParentTop="true"

         />
    <!--CameraSurface layout_height will be changed during it loading process -->
</RelativeLayout>

      

AndroidManifest is set to portrait:

  <activity android:label="@string/app_name" android:name=".MixView" 
    android:screenOrientation="portrait"  
    android:launchMode="singleTop" >

      

actual images:

enter image description here - portrait with a rotary device

enter image description here - rotating device landscape

Found in the same themes: Android - camera preview sideways , Android camera rotates but Ive got the same result with their code

And here you could see the wrong aspect ratio of the image. How do I display the expanded and scaled camera view in the correct proportions?

Portions of the code were taken from the Mixare open source project, http://www.mixare.org/

+3


source to share


1 answer


I know it is too late to answer this question, but this problem can be fixed by setting the orientation of the camera display to 90 degrees i.e. by adding the following line after camera.open()

to SurfaceCreated

the CameraSurface

class method

camera.setDisplayOrientation(90);



Hope this helps others having the same problem.

+1


source







All Articles