SurfaceView 的裁剪相机预览
Crop camera preview for SurfaceView
我有一个用于条形码扫描的 SurfaceView(来自 this tutorial)。
<SurfaceView
android:id="@+id/camera_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" />
需要设置屏幕高度为 1/4 的裁剪相机预览。
我根据屏幕尺寸设置了视图尺寸:
cameraView = (SurfaceView) findViewById(R.id.camera_view);
final DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(metrics.widthPixels, metrics.heightPixels / 4);
cameraView.setLayoutParams(layoutParams);
但是相机预览只是缩小了!
我是这样设置的
final BarcodeDetector barcodeDetector =
new BarcodeDetector.Builder(this)
.setBarcodeFormats(Barcode.ALL_FORMATS)
.build();
final CameraSource cameraSource = new CameraSource
.Builder(this, barcodeDetector)
.setRequestedPreviewSize(metrics.widthPixels, metrics.heightPixels / 4)
.setAutoFocusEnabled(true)
.build();
cameraView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
cameraSource.start(cameraView.getHolder());
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
cameraSource.stop();
}
});
如何裁剪相机预览?只需要底部的 1/4 部分。
还需要添加一个带有矩形取景器的透明层。
您可能希望使用的是 TextureView
。 SurfaceViews
并非设计用于裁剪 - 视频显示调整为 SurfaceView
的大小是预期的行为。
另一方面,从 API 级别 14+ 开始可用的 TextureViews
允许您设置 .setTransform(Matrix matrix)
,其中矩阵包含有关如何缩放的数据视频,.setTranslationX(float x)
和 .setTranslationY(float y)
裁剪视频。有一个很好的例子 here.
如果您绝对必须使用 SurfaceView,我建议您考虑使用 GLSurfaceView
和可缩放视频的自定义渲染器。一个好的起点是 .
您无法通过缩小视图来实现裁剪。可以用另一种布局叠加相机预览,有效隐藏图片上3/4
我用ViewGroup解决了。
布局中:
<com.superup.smartshelf.barcode.BarcodeCameraPreview
android:id="@+id/preview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.25"/>
在class中:
public class BarcodeCameraPreview extends ViewGroup {
private SurfaceView mSurfaceView;
public BarcodeCameraPreview(final Context context, AttributeSet attrs) {
super(context, attrs);
mSurfaceView = new SurfaceView(context);
mSurfaceView.getHolder().addCallback(new SurfaceCallback());
addView(mSurfaceView);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// crop view
int actualPreviewWidth = getResources().getDisplayMetrics().widthPixels;
int actualPreviewHeight = getResources().getDisplayMetrics().heightPixels;
if (mSurfaceView != null) {
mSurfaceView.layout(0, 0, actualPreviewWidth, actualPreviewHeight);
}
}
// camera methods
}
在activity中:
BarcodeCameraPreview camera = (BarcodeCameraPreview) findViewById(R.id.preview);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(metrics.widthPixels, metrics.heightPixels / 4);
camera.setLayoutParams(layoutParams);
我有一个用于条形码扫描的 SurfaceView(来自 this tutorial)。
<SurfaceView
android:id="@+id/camera_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" />
需要设置屏幕高度为 1/4 的裁剪相机预览。
我根据屏幕尺寸设置了视图尺寸:
cameraView = (SurfaceView) findViewById(R.id.camera_view);
final DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(metrics.widthPixels, metrics.heightPixels / 4);
cameraView.setLayoutParams(layoutParams);
但是相机预览只是缩小了!
我是这样设置的
final BarcodeDetector barcodeDetector =
new BarcodeDetector.Builder(this)
.setBarcodeFormats(Barcode.ALL_FORMATS)
.build();
final CameraSource cameraSource = new CameraSource
.Builder(this, barcodeDetector)
.setRequestedPreviewSize(metrics.widthPixels, metrics.heightPixels / 4)
.setAutoFocusEnabled(true)
.build();
cameraView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
cameraSource.start(cameraView.getHolder());
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
cameraSource.stop();
}
});
如何裁剪相机预览?只需要底部的 1/4 部分。
还需要添加一个带有矩形取景器的透明层。
您可能希望使用的是 TextureView
。 SurfaceViews
并非设计用于裁剪 - 视频显示调整为 SurfaceView
的大小是预期的行为。
另一方面,从 API 级别 14+ 开始可用的 TextureViews
允许您设置 .setTransform(Matrix matrix)
,其中矩阵包含有关如何缩放的数据视频,.setTranslationX(float x)
和 .setTranslationY(float y)
裁剪视频。有一个很好的例子 here.
如果您绝对必须使用 SurfaceView,我建议您考虑使用 GLSurfaceView
和可缩放视频的自定义渲染器。一个好的起点是
您无法通过缩小视图来实现裁剪。可以用另一种布局叠加相机预览,有效隐藏图片上3/4
我用ViewGroup解决了。
布局中:
<com.superup.smartshelf.barcode.BarcodeCameraPreview
android:id="@+id/preview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.25"/>
在class中:
public class BarcodeCameraPreview extends ViewGroup {
private SurfaceView mSurfaceView;
public BarcodeCameraPreview(final Context context, AttributeSet attrs) {
super(context, attrs);
mSurfaceView = new SurfaceView(context);
mSurfaceView.getHolder().addCallback(new SurfaceCallback());
addView(mSurfaceView);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// crop view
int actualPreviewWidth = getResources().getDisplayMetrics().widthPixels;
int actualPreviewHeight = getResources().getDisplayMetrics().heightPixels;
if (mSurfaceView != null) {
mSurfaceView.layout(0, 0, actualPreviewWidth, actualPreviewHeight);
}
}
// camera methods
}
在activity中:
BarcodeCameraPreview camera = (BarcodeCameraPreview) findViewById(R.id.preview);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(metrics.widthPixels, metrics.heightPixels / 4);
camera.setLayoutParams(layoutParams);