我有一个 Android 应用程序需要全屏显示相机预览,无论预览大小如何,都getSupportedPreviewSizes()
不会失真。我希望这会在高度或宽度上裁剪预览,但这与我无关。我寻求这样做的原因是因为某些 android 相机(例如三星 Galaxy SII 前置摄像头)不会返回与显示器具有相同纵横比的任何预览,因此需要拉伸和剪裁。
是否可以将相机预览完全放大到大于显示尺寸的视图?通过简单地将表面视图的布局参数设置为 match_parent,可以将 SurfaceView 增大到大于返回的预览像素尺寸,但这会导致某些方向的失真,并且只有在预览填满显示之前才有可能。这似乎表明在显示器之外进行预览是不可能的,并且硬件(或操作系统)限制了这种行为。
关于该主题还有另一个问题,但该问题声称无法创建大于屏幕尺寸的 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 表面,但这显然在全彩色上可能太慢了。如果可以简单地拉伸和剪切相机预览,那也是一种痛苦。
在此先感谢您对解决方案的任何尝试。