SurfaceView的裁剪相机预览

时间:2016-03-01 18:40:45

标签: android android-camera 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部分。

还需要添加一个带有矩形取景器的透明层。

3 个答案:

答案 0 :(得分:3)

您可能希望使用的是TextureViewSurfaceViews并非旨在裁剪 - 视频显示调整为SurfaceView的大小是预期的行为。

另一方面,API级别14以上的TextureViews允许您设置.setTransform(Matrix matrix),其中矩阵包含有关如何缩放视频的数据,{{1 }和.setTranslationX(float x)裁剪视频。有一个很好的例子here

如果您绝对必须使用SurfaceView,我建议您使用.setTranslationY(float y)和缩放视频的自定义渲染器。一个很好的起点是here

答案 1 :(得分:2)

我用ViewGroup解决了它。

布局:

    <com.superup.smartshelf.barcode.BarcodeCameraPreview
        android:id="@+id/preview"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.25"/>

课堂上:

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

}

活动:

BarcodeCameraPreview camera = (BarcodeCameraPreview) findViewById(R.id.preview);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(metrics.widthPixels, metrics.heightPixels / 4);
camera.setLayoutParams(layoutParams);

答案 2 :(得分:1)

您无法通过缩小视图来实现裁剪。您可以使用其他布局覆盖相机预览,并有效隐藏图片的上3/4。