2012-07-04 38 views
23

我有一個Android應用程序,需要全屏顯示相機預覽,而不管getSupportedPreviewSizes()給出的預覽大小是否沒有失真。我希望這會在高度或寬度上裁剪一些預覽,但這並不關心我。我試圖這樣做的原因是因爲某些安卓相機(例如三星Galaxy SII前置相機)不會以與顯示器相同的寬高比返回任何預覽,因此需要拉伸和裁剪。將相機預覽擬合成大於顯示器的SurfaceView

是否可以將相機預覽完全擴展到大於顯示尺寸的視圖?通過簡單地將表面視圖的佈局參數設置爲match_parent,可以增大比預覽像素尺寸大的SurfaceView,但這會導致某些方向的扭曲,直到預覽填充顯示爲止。這似乎表明預覽不在顯示器之外,硬件(或操作系統)限制了這種行爲。

關於該主題有another question,但該問題聲稱不可能創建大於屏幕尺寸的SurfaceView,這是錯誤的,正如我在記錄中發現的那樣。然而,似乎是這樣的情況是,相機預覽不能增長到巨大的SurfaceView的全尺寸。

我嘗試:

我有個親戚佈局,內它的FrameLayout,並在我創建一個SurfaceView。整個相對佈局的寬度設置爲635dp,這是設備屏幕尺寸的兩倍。在此的FrameLayout匹配尺寸也是如此的SurfaceView(編程後加)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/camera_activity_layout" 
    android:layout_width="635dp" 
    android:layout_height="match_parent" > 

    <FrameLayout 
     android:id="@+id/camera_preview" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 
    </FrameLayout> 

</RelativeLayout> 

以下是獲取和設置預覽大小不同的代碼。在這裏,我想讓相機預覽展開以填充整個FrameLayout(雙倍的屏幕寬度)。視圖完全正常地顯示和破壞,所以我刪除了與這個特定問題無關的代碼,因爲它分散了基本問題,並且我試圖輕鬆簡單地將視圖擴大到大於顯示大小。

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 

    ... 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     Camera.Parameters parameters = mCamera.getParameters(); 
     final DisplayMetrics dm = this.getResources().getDisplayMetrics(); 
      //getBestPreviewSize returns the best preview size, don't worry 
      //but some devices do not return one for all camera matching the aspect ratio 
     cameraSize = getBestPreviewSize(parameters, dm.heightPixels, dm.widthPixels); 

     if (cameraSize!=null) { 
      parameters.setPreviewSize(cameraSize.width, cameraSize.height); 
      mCamera.setParameters(parameters); 
     } 

     FrameLayout.LayoutParams frameParams = (FrameLayout.LayoutParams) this.getLayoutParams(); 

     frameParams.width = 800; //For argument's sake making this ~double the width of the display. Same result occurs if I use MATCH_PARENT 
     frameParams.height = LayoutParams.MATCH_PARENT; 
     this.setLayoutParams(frameParams); 

     try { 
      mCamera.setPreviewDisplay(mHolder); 
      mCamera.startPreview(); 

      Log.d("surfChange","W/H of CamPreview (child) is "+this.getWidth()+"/"+this.getHeight()+" while parent is "); 
      Log.d("surfChange","W/H of holder (child) is "+mHolder.getSurfaceFrame().width()+"/"+mHolder.getSurfaceFrame().height()+" while parent is "); 
     } catch (Exception e){ 
     } 
    } 
}; 

我所關注的是,在這一努力成功的唯一途徑就是以某種方式呈現到OpenGL的表面,但這個apparently可能是全綵色太慢。如果相機預覽可以簡單地拉伸和裁剪,這也是一種痛苦。

在此先感謝解決方案的任何嘗試。

+0

你可以發表你的post oncreate()代碼。或者你在哪裏調用setcontentview()方法 –

+0

你爲什麼對代碼感興趣?這是非常基本的,只需將內容視圖設置爲我上面共享的xml即可。 –

+0

行,所以我認爲擴大視圖超出窗口管理器是不可能的,我也找了放大視頻的部分,但使用的所有表面視圖和自定義視頻查看我天璣得到任何視頻不會被裁剪超出大小 –

回答

12

好吧,我知道這是非常晚的答案,但它是可能的。以下是Android SDK示例中的代碼。要查看代碼的其餘部分實現這個下載Android SDK的樣品和去Samples/android-10(one I used, could try whichever you want to target)/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.java

class PreviewSurface extends ViewGroup implements SurfaceHolder.Callback { 
... 
@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; 
     if (mPreviewSize != null) { 
      previewWidth = mPreviewSize.width; 
      previewHeight = mPreviewSize.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); 
     } 
    } 
} 
} 

這段代碼是爲了適應預覽到最小尺寸(即不弄亂aspcect比)中心在另一個維度上有黑條。但是,如果您將>翻轉爲<,您可以實現您想要的效果。例如:

if (width * previewHeight < height * previewWidth) {...