2013-02-19 72 views
1

我寫了一個相機應用(活動),其採用的圖片,但顯示攝像機的實時畫面並不好看預覽,這是一個有點高,像這樣: enter image description here安卓相機預覽不會好看

這裏是我的攝像頭預覽代碼:

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> 

回答

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

試試這個代碼已用於項目,希望這將有助於

+0

想你的代碼。你能否也發佈IQPhotoHandler類? – akhyar 2014-02-07 14:26:28