想要在Android中使用ZBar扫描仪库进行更大的相机预览

时间:2016-05-25 12:29:22

标签: android android-camera zbar image-scanner

我在Android应用中使用ZBarScannerActivity。但我在设备上获得了一个小的表面视图。实际上我想要全屏幕相机预览来扫描QR码。

任何帮助将不胜感激。 谢谢。 这是ZbarScanner活动的代码

package com.dm.zbar.android.scanner;


public class ZBarScannerActivity extends Activity implements Camera.PreviewCallback, ZBarConstants {

private static final String TAG = "ZBarScannerActivity";
private CameraPreview mPreview;
private Camera mCamera;
private ImageScanner mScanner;
private Handler mAutoFocusHandler;
private boolean mPreviewing = true;

static {
    System.loadLibrary("iconv");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if(!isCameraAvailable()) {
        // Cancel request if there is no rear-facing camera.
        cancelRequest();
        return;
    }


    // Hide the window title.
    //requestWindowFeature(Window.FEATURE_NO_TITLE);
    //getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);


    mAutoFocusHandler = new Handler();

    // Create and configure the ImageScanner;
    setupScanner();

    // Create a RelativeLayout container that will hold a SurfaceView,
    // and set it as the content of our activity.
    mPreview = new CameraPreview(this, this, autoFocusCB);
    setContentView(mPreview);
}




public void setupScanner() {
    mScanner = new ImageScanner();
    mScanner.setConfig(0, Config.X_DENSITY, 3);
    mScanner.setConfig(0, Config.Y_DENSITY, 3);

    int[] symbols = getIntent().getIntArrayExtra(SCAN_MODES);
    if (symbols != null) {
        mScanner.setConfig(Symbol.NONE, Config.ENABLE, 0);
        for (int symbol : symbols) {
            mScanner.setConfig(symbol, Config.ENABLE, 1);
        }
    }
}

@Override
protected void onResume() {
    super.onResume();

    // Open the default i.e. the first rear facing camera.
    mCamera = Camera.open();
    if(mCamera == null) {
        // Cancel request if mCamera is null.
        cancelRequest();
        return;
    }

    mPreview.setCamera(mCamera);
    mPreview.showSurfaceView();

    mPreviewing = true;
}

@Override
protected void onPause() {
    super.onPause();

    // Because the Camera object is a shared resource, it's very
    // important to release it when the activity is paused.
    if (mCamera != null) {
        mPreview.setCamera(null);
        mCamera.cancelAutoFocus();
        mCamera.setPreviewCallback(null);
        mCamera.stopPreview();
        mCamera.release();

        // According to Jason Kuang on http://stackoverflow.com/questions/6519120/how-to-recover-camera-preview-from-sleep,
        // there might be surface recreation problems when the device goes to sleep. So lets just hide it and
        // recreate on resume
        mPreview.hideSurfaceView();

        mPreviewing = false;
        mCamera = null;
    }
}

public boolean isCameraAvailable() {
    PackageManager pm = getPackageManager();
    return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA);
}

public void cancelRequest() {
    Intent dataIntent = new Intent();
    dataIntent.putExtra(ERROR_INFO, "Camera unavailable.");
    setResult(Activity.RESULT_CANCELED, dataIntent);
    finish();
}

public void onPreviewFrame(byte[] data, Camera camera) {
    Camera.Parameters parameters = camera.getParameters();
    Camera.Size size = parameters.getPreviewSize();

    Image barcode = new Image(size.width, size.height, "Y800");
    barcode.setData(data);

    int result = mScanner.scanImage(barcode);

    if (result != 0) {
        mCamera.cancelAutoFocus();
        mCamera.setPreviewCallback(null);
        mCamera.stopPreview();
        mPreviewing = false;
        SymbolSet syms = mScanner.getResults();
        for (Symbol sym : syms) {
            String symData = sym.getData();
            if (!TextUtils.isEmpty(symData)) {
                Intent dataIntent = new Intent();
                dataIntent.putExtra(SCAN_RESULT, symData);
                dataIntent.putExtra(SCAN_RESULT_TYPE, sym.getType());
                setResult(Activity.RESULT_OK, dataIntent);
                finish();
                break;
            }
        }
    }
}
private Runnable doAutoFocus = new Runnable() {
    public void run() {
        if(mCamera != null && mPreviewing) {
            mCamera.autoFocus(autoFocusCB);
        }
    }
};

// Mimic continuous auto-focusing
Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
    public void onAutoFocus(boolean success, Camera camera) {
        mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
    }
};

和CameraPreview类 class CameraPreview扩展ViewGroup实现SurfaceHolder.Callback {     private final String TAG =“CameraPreview”;

SurfaceView mSurfaceView;
SurfaceHolder mHolder;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
Camera mCamera;
PreviewCallback mPreviewCallback;
AutoFocusCallback mAutoFocusCallback;

CameraPreview(Context context, PreviewCallback previewCallback, AutoFocusCallback autoFocusCb) {
    super(context);

    mPreviewCallback = previewCallback;
    mAutoFocusCallback = autoFocusCb;
    mSurfaceView = new SurfaceView(context);
    addView(mSurfaceView);

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

public void setCamera(Camera camera) {
    mCamera = camera;
    if (mCamera != null) {
        //Changes********
        mCamera.setDisplayOrientation(90);
        mCamera.getParameters().getMaxNumFocusAreas();
        mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();

        requestLayout();
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    // We purposely disregard child measurements because act as a
    // wrapper to a SurfaceView that centers the camera preview instead
    // of stretching it.



    final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
    final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
    setMeasuredDimension(width, height);

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

@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);
        }
    }
}

public void hideSurfaceView() {
    mSurfaceView.setVisibility(View.INVISIBLE);
}

public void showSurfaceView() {
    mSurfaceView.setVisibility(View.VISIBLE);
}

public void surfaceCreated(SurfaceHolder holder) {
    // The Surface has been created, acquire the camera and tell it where
    // to draw.
    try {
        if (mCamera != null) {
            mCamera.setPreviewDisplay(holder);
        }
    } catch (IOException exception) {
        Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
    }
}

public void surfaceDestroyed(SurfaceHolder holder) {
    // Surface will be destroyed when we return, so stop the preview.
    if (mCamera != null) {
        mCamera.cancelAutoFocus();
        mCamera.stopPreview();
    }
}


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

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

    int targetHeight = h;

    // Try to find an size match aspect ratio and size

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

    // Cannot find the one match the aspect ratio, ignore the requirement
    if (optimalSize == null) {
        minDiff = Double.MAX_VALUE;
        for (Size size : sizes) {
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
    }
    return optimalSize;
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    if (holder.getSurface() == null){
      // preview surface does not exist
      return;
    }

    if (mCamera != null) {
        // Now that the size is known, set up the camera parameters and begin
        // the preview.
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        requestLayout();

       // mCamera.setDisplayOrientation(90);
        mCamera.setParameters(parameters);
        mCamera.setPreviewCallback(mPreviewCallback);
        mCamera.startPreview();
        mCamera.autoFocus(mAutoFocusCallback);
    }
}

}

请帮助我了解相机预览尺寸的情况。

2 个答案:

答案 0 :(得分:6)

  

我在设备上获得了一个小的表面视图。实际上我想要全屏幕相机预览来扫描QR码

  • 如果您说相机不占用整个屏幕,请尝试更改

    android:layout_width="match_parent"
    android:layout_height="match_parent"
    
<{1}}和SurfaceView

  • 如果您想要全屏扫描区域,请点击此处:

    parent_layout

结果:

enter image description here

答案 1 :(得分:0)

我通过从Camerapreview Class

中删除以下代码解决了这个问题
 if (mPreviewSize != null) {
        previewWidth = mPreviewSize.width;
        previewHeight = mPreviewSize.height;
    }
它对我有用。 它会给你全屏相机。 谢谢。