我写了一个拍照的相机应用程序(活动),但显示相机实时图片的预览看起来并不好看,它有点高,像这样:
以下是我的相机预览的代码:
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
{
private SurfaceHolder mHolder ;
private Camera mCamera;
public CameraPreview(Context context , Camera camera)
{
super(context) ;
mCamera = camera ;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder)
{
try
{
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
catch(IOException e)
{
Log.d(TAG,"Camera Preview Failed!: "+e.getMessage());
}
}
public void surfaceChanged(SurfaceHolder holder , int m , int n , int w)
{
}
public void surfaceDestroyed(SurfaceHolder holder)
{
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:id="@+id/camera_preview"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="0.86" />
<Button
android:id="@+id/button_capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:gravity="center"
android:onClick="capture"
android:text="Capture" />
<Button
android:id="@+id/button_accept"
android:layout_width="115dp"
android:layout_height="wrap_content"
android:text="Accept"
android:visibility="gone"
android:onClick = "accept" />
<Button
android:id="@+id/button_retake"
android:layout_width="107dp"
android:layout_height="wrap_content"
android:text="Retake"
android:visibility="gone"
android:onClick = "retake"/>
</LinearLayout>
答案 0 :(得分:2)
public class IQCameraView extends ViewGroup implements SurfaceHolder.Callback {
public static final int CAMERA_ERROR = 0;
public static final int CAMERA_RESULT = 1;
private final String TAG = "Preview";
private SurfaceView mSurfaceView;
private SurfaceHolder mHolder;
private Size mPreviewSize;
private List<Size> mSupportedPreviewSizes;
private Camera mCamera;
private boolean mCameraActive;
private IQCameraCallback mCallback;
/**
* @param mCallback
* of type IQCameraCallback
* @return of type null setter function for mCallback
* @since 10 Oct 2012
*/
public void setmCallback(IQCameraCallback mCallback) {
this.mCallback = mCallback;
}
/**
* @param context
* of type Context
* @return of type boolean function which will check the system has a camera
* or not
* @since 10 Oct 2012
*/
public static boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
return true;
} else {
return false;
}
}
/**
* @param context
* Constructor function
* @since 16 Oct 2012
*/
public IQCameraView(Context context) {
super(context);
mSurfaceView = new SurfaceView(context);
addView(mSurfaceView);
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
/**
* @param camera
* of type Camera
* @return of type null setter function for mCamera
* @since 16 Oct 2012
*/
public void setCamera(Camera camera) {
mCamera = camera;
if (mCamera != null) {
mSupportedPreviewSizes = mCamera.getParameters()
.getSupportedPreviewSizes();
requestLayout();
}
}
/**
* @param of
* type null
* @return of type null function which will get the current frame from the
* camera
* @since 16 Oct 2012
*/
public void takePicture() {
if (null != mCamera && mCameraActive) {
mCamera.takePicture(null, null, new IQPhotoHandler(getContext(),
this));
}
}
/**
* @param result
* of type String
* @return of type null function which will be called when the image save is
* complete
* @since 16 Oct 2012
*/
public void onImageCapture(final String result) {
if (null != mCallback) {
mCallback.onCameraCallback(CAMERA_RESULT, result);
}
mCamera.startPreview();
}
/*
* (non-Javadoc)
*
* @see android.view.View#onMeasure(int, int)
*
* @since 16 Oct 2012
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// We purposely disregard child measurements because act as a
// Wrapper to a SurfaceView that centers the camera preview instead of
// stretching it.
final int width = resolveSize(getSuggestedMinimumWidth(),
widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(),
heightMeasureSpec);
setMeasuredDimension(width, height);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getPreviewSize(mSupportedPreviewSizes, width, height);
}
}
/*
* (non-Javadoc)
*
* @see android.view.ViewGroup#onLayout(boolean, int, int, int, int)
*
* @since 16 Oct 2012
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed && getChildCount() > 0) {
final View child = getChildAt(0);
final int width = r - l;
final int height = b - t;
int previewWidth = width;
int previewHeight = height;
// Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth) {
final int scaledChildWidth = previewWidth * height
/ previewHeight;
child.layout((width - scaledChildWidth) / 2, 0,
(width + scaledChildWidth) / 2, height);
} else {
final int scaledChildHeight = previewHeight * width
/ previewWidth;
child.layout(0, (height - scaledChildHeight) / 2, width,
(height + scaledChildHeight) / 2);
}
}
}
/**
* @param of
* type null
* @return of type null function which will release teh camera
* @since 16 Oct 2012
*/
public void releaseCamera() {
if (null != mCamera && mCameraActive) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
mCameraActive = false;
}
/*
* (non-Javadoc)
*
* @see
* android.view.SurfaceHolder.Callback#surfaceCreated(android.view.SurfaceHolder
* )
*
* @since 16 Oct 2012
*/
public void surfaceCreated(SurfaceHolder holder) {
try {
if (mCamera != null) {
mCamera.setPreviewDisplay(holder);
}
} catch (IOException e) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", e);
}
}
/*
* (non-Javadoc)
*
* @see android.view.SurfaceHolder.Callback#surfaceDestroyed(android.view.
* SurfaceHolder)
*
* @since 16 Oct 2012
*/
public void surfaceDestroyed(SurfaceHolder holder) {
releaseCamera();
}
/*
* (non-Javadoc)
*
* @see
* android.view.SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder
* , int, int, int)
*
* @since 16 Oct 2012
*/
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
parameters.setPictureSize(mPreviewSize.width, mPreviewSize.height);
parameters.setPictureFormat(PixelFormat.JPEG);
mCamera.setDisplayOrientation(90);
requestLayout();
try {
mCamera.setParameters(parameters);
} catch (Exception e) {
System.out.print("hih");
}
mCamera.startPreview();
mCameraActive = true;
}
/**
* @param sizes
* of type List
* @param w
* of type int
* @param h
* of type int
* @return optionalSize of type Size function which will find the exact size
* required for teh camera view
* @since 16 Oct 2012
*/
private Size getPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
if (sizes == null)
return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
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;
}
/**
* @author rajeshcp
* @since 16 Oct 2012
*/
public static interface IQCameraCallback {
public void onCameraCallback(final int type, final Object param);
}
}
试试这个代码用于项目,希望这会有所帮助