自定义相机与Android中的表面视图问题

时间:2014-10-29 04:26:19

标签: android camera surfaceview

我正在研究一种条形码扫描仪应用程序 我的条形码扫描仪和表面视图完美无缺。但是,在维护相机的宽高比时,父视图布局在较高版本的Android设备(如nexus和motog)中从底部略微削减,如第一张图片中所示。在较低版本的Android设备中我没有&t; t面对像micromax帆布这样的问题。

这是两张图片, 在第1张图片中,包含相机视图的第1个标签,以及在维护相机的纵横比期间从底部略微剪切的父视图,在第2个标签的第2张图像中,它看起来很完美。

enter image description here enter image description here


这是我的cameraPreview类,

公共类CameraPreview扩展了SurfaceView实现         SurfaceHolder.Callback {

private SurfaceHolder mHolder;
private Camera mCamera;

private List<Camera.Size> mSupportedPreviewSizes;
private Camera.Size mPreviewSize;

private PreviewCallback previewCallback;
private AutoFocusCallback autoFocusCallback;

@SuppressWarnings("deprecation")
public CameraPreview(Context context, Camera camera,
        PreviewCallback previewCb, AutoFocusCallback autoFocusCb) {

    super(context);
    mCamera = camera;
    previewCallback = previewCb;
    autoFocusCallback = autoFocusCb;

    // supported preview sizes
    mSupportedPreviewSizes = mCamera.getParameters()
            .getSupportedPreviewSizes();

    // Install a SurfaceHolder.Callback so we get notified when the
    // underlying surface is created and destroyed.
    mHolder = getHolder();
    mHolder.addCallback(this);

    // deprecated setting, but required on Android versions prior to 3.0
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public void surfaceCreated(SurfaceHolder holder) {
    // The Surface has been created, now tell the camera where to draw the
    // preview.
    try {
        mCamera.setPreviewDisplay(holder);
    } catch (IOException e) {

        // Log.d("DBG", "Error setting camera preview: " + e.getMessage());
    }
}

public void surfaceDestroyed(SurfaceHolder holder) {
    // Camera preview released in activity
}

public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    /*
     * If your preview can change or rotate, take care of those events here.
     * Make sure to stop the preview before resizing or reformatting it.
     */
    if (mHolder.getSurface() == null) {
        // preview surface does not exist
        return;
    }

    // stop preview before making changes
    try {
        mCamera.stopPreview();
    } catch (Exception e) {
        // ignore: tried to stop a non-existent preview
    }

    // set preview size and make any resize, rotate or reformatting changes
    // here
    // start preview with new settings
    try {

        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        parameters.setPictureSize(mPreviewSize.width, mPreviewSize.height);
        mCamera.setParameters(parameters);
        mCamera.setDisplayOrientation(90);
        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();

        mCamera.setPreviewCallback(previewCallback);
        mCamera.autoFocus(autoFocusCallback);

    } catch (Exception e) {
        // Log.d("DBG", "Error starting camera preview: " + e.getMessage());
    }
}

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

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

    float ratio;
    if (mPreviewSize.height >= mPreviewSize.width)
        ratio = (float) mPreviewSize.height / (float) mPreviewSize.width;
    else
        ratio = (float) mPreviewSize.width / (float) mPreviewSize.height;

    // One of these methods should be used, second method squishes preview
    // slightly
    setMeasuredDimension(width, (int) (width * ratio));
    // setMeasuredDimension((int) (width * ratio), height);
}

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w,
        int h) {
    final double ASPECT_TOLERANCE = 0.1;
    double targetRatio = (double) h / w;

    if (sizes == null)
        return null;

    Camera.Size optimalSize = null;
    double minDiff = Double.MAX_VALUE;

    int targetHeight = h;

    for (Camera.Size size : sizes) {
        double ratio = (double) size.height / size.width;
        if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
            continue;

        if (Math.abs(size.height - targetHeight) < minDiff) {
            optimalSize = size;
            minDiff = Math.abs(size.height - targetHeight);
        }
    }

    if (optimalSize == null) {
        minDiff = Double.MAX_VALUE;
        for (Camera.Size size : sizes) {
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
    }

    return optimalSize;
}

}


任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

最后,我找到了一点解决方案,
我仍然没有得到真正的问题,但我只是为我的框架布局设置填充,如下所示,我在添加表面视图,它解决了我的问题。

android:padding="0.2dp"

我的framelayout如下所示,我正在添加表面视图,

    <FrameLayout
        android:id="@+id/layout_frameScanner"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:layout_centerInParent="true"
        android:background="@color/color_black"
        android:padding="0.2dp" >
    </FrameLayout>