2013-08-28 31 views
2

我打算使用BeyondAR框架開發一個android應用程序。我嘗試在屏幕的前半部分使用CameraView組件(應用程序只能在肖像模式下運行),但是當我旋轉相機90度時,圖像拉伸並且寬高比錯了。任何幫助?CameraView中的人像模式

CameraView類(Beyondar框架)

public class CameraView extends SurfaceView implements SurfaceHolder.Callback, 
    Camera.PictureCallback { 

/** 
* 
* @author Joan Puig Sanz ([email protected]) 
* 
*/ 
public static interface IPictureCallback { 
    /** 
    * This method is called when the snapshot of the camera is ready. If 
    * there is an error, the image will be null 
    * 
    * @param picture 
    */ 
    void onPictureTaken(Bitmap picture); 
} 

private SurfaceHolder mHolder; 
private Camera mCamera; 
private IPictureCallback mCameraCallback; 
private BitmapFactory.Options mOptions; 

private Size mPreviewSize; 
private List<Size> mSupportedPreviewSizes; 
private List<String> mSupportedFlashModes; 

public CameraView(Context context) { 
    super(context); 
    init(context); 
} 

public CameraView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    init(context); 
} 

public CameraView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    init(context); 
} 

private void init(Context context) { 
    mHolder = getHolder(); 
    mHolder.addCallback(this); 

    try { 
     mCamera = Camera.open(); 
     //mCamera.setDisplayOrientation(90); 


     //Camera.Parameters params = mCamera.getParameters(); 
     //params.setPreviewSize(427, 1240); 
     //mCamera.setParameters(params); 
     setCamera(mCamera); 
    } catch (Exception e) { 
     Log.e(Constants.TAG, "ERROR: Unable to open the camera", e); 
    } 

    if (android.os.Build.VERSION.SDK_INT <= 10) {// Android 2.3.x or lower 
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 
} 

public void setCamera(Camera camera) { 
    mCamera = camera; 
    if (mCamera != null) { 
     mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes(); 
     mSupportedFlashModes = mCamera.getParameters().getSupportedFlashModes(); 
     // Set the camera to Auto Flash mode. 
     if (mSupportedFlashModes != null 
       && mSupportedFlashModes.contains(Camera.Parameters.FLASH_MODE_AUTO)) { 
      Camera.Parameters parameters = mCamera.getParameters(); 
      parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO); 
      //parameters.setPreviewSize(300, 200); 
      mCamera.setParameters(parameters); 
     } 
    } 
} 

public void setSupportedPreviewSizes(List<Size> supportedPreviewSizes) { 
    mSupportedPreviewSizes = supportedPreviewSizes; 
} 

public Size getPreviewSize() { 
    return mPreviewSize; 
} 

public void surfaceCreated(SurfaceHolder holder) { 
    // The Surface has been created, acquire the camera and tell it where 
    // to draw. 
    try { 

     if (mCamera == null) { 
      init(getContext()); 
      if (mCamera == null) { 
       return; 
      } 
     } 

     mCamera.setPreviewDisplay(holder); 
    } catch (IOException exception) { 
     if (mCamera != null) { 
      mCamera.release(); 
     } 
     mCamera = null; 
     Log.e(Constants.TAG, "CameraView -- ERROR en SurfaceCreated", exception); 
    } 
} 

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

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); 
    final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); 
    setMeasuredDimension(width, height); 

    if (mSupportedPreviewSizes != null) { 
     mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height); 
    } 

    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
} 

private Size getOptimalPreviewSize(List<Size> sizes, int width, int height) { 

    Size result = null; 

    for (Camera.Size size : sizes) { 
     if (size.width <= width && size.height <= height) { 
      if (result == null) { 
       result = size; 
      } else { 
       int resultArea = result.width * result.height; 
       int newArea = size.width * size.height; 

       if (newArea > resultArea) { 
        result = size; 
       } 
      } 
     } 
    } 

    return result; 
} 

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    if (mCamera == null || getPreviewSize() == null) { 
     return; 
    } 

    Camera.Parameters parameters = mCamera.getParameters(); 
    Size previewSize = getPreviewSize(); 
    parameters.setPreviewSize(previewSize.width, previewSize.height); 

    mCamera.setParameters(parameters); 
    previewCamera(); 

} 

@Override 
public void onPictureTaken(byte[] imageData, Camera camera) { 
    if (imageData != null && mCameraCallback != null) { 
     mCameraCallback.onPictureTaken(StoreByteImage(imageData)); 
    } 
    previewCamera(); 
} 

public void previewCamera() { 
    if (mCamera == null){ 
     return; 
    } 
    try { 
     mCamera.setPreviewDisplay(mHolder); 
     mCamera.startPreview(); 
    } catch (Exception e) { 
     Log.d(Constants.TAG, "Cannot start preview.", e); 
    } 
} 

private Bitmap StoreByteImage(byte[] imageData) { 

    Bitmap myImage = DebugBitmap.decodeByteArray(imageData, 0, imageData.length, mOptions); 

    imageData = null; 
    System.gc(); 

    return myImage; 
} 

public void tackePicture(IPictureCallback cameraCallback) { 
    BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inSampleSize = 4; 
    tackePicture(cameraCallback, options); 
} 

public void tackePicture(IPictureCallback cameraCallback, BitmapFactory.Options options) { 
    if (mCamera == null) { 
     return; 
    } 
    mCameraCallback = cameraCallback; 
    mCamera.takePicture(null, this, this); 
    mOptions = options; 
} 


} 

編輯

MyLayout xml文件

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="0dip" 
    android:layout_weight="1" 
    android:orientation="horizontal" 
    android:paddingBottom="@dimen/padding" 
    android:paddingLeft="@dimen/padding" 
    android:paddingRight="@dimen/padding" 
    android:paddingTop="@dimen/padding" > 

    <FrameLayout 
    android:orientation="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    > 
    <com.beyondar.android.opengl.views.BeyondarGLSurfaceView 
    android:id="@+id/customGLSurface" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" />  
    <com.beyondar.android.views.CameraView 
    android:id="@+id/camera" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" /> 

<TextView 
    android:id="@+id/labelText" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Touch an AR Object" 
    android:background="#000000" 
    android:textColor="#FFFFFF" 
    /> 


    </FrameLayout> 
    </LinearLayout 
+0

什麼是你的佈局? – Turnsole

+0

我只是編輯我的帖子! – user2352548

+0

你說「應用程序只能在肖像模式下運行」,你的意思是你已經在處理旋轉,並將活動限制爲肖像模式? – Turnsole

回答

1

如果你看一下BeyondAR示例應用程序,你可以看到它有一個類似的問題在於相機的圖像被拉伸以填滿屏幕,因此在兩個橫向的縱向中都沒有適當的縱橫比。在使用相機預覽時,這是一個常見問題,因爲它在第一次啓動時鎖定到特定方向。

爲了達到這個目的,您需要將旋轉視圖調整爲與設備相機匹配的寬高比。 Here's the official Android guide

注意具體稱爲「設置預覽方向」的部分。

+0

感謝您的回答,但可以在我的代碼中解釋它嗎?對不起,但我是begginer – user2352548

+0

如何根據您的指示編輯CameraView類? – user2352548

+0

BeyondAR庫作爲Android庫項目發佈,因此,只要將它加載到IDE中,就可以隨心所欲地編輯庫。你在用什麼IDE? – Turnsole