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:
- portrait with a rotary device
- 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/
source to share
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.
source to share