当前位置: 首页 > 知识库问答 >
问题:

想要更大的相机预览使用ZBar扫描器库在Android

仇建茗
2023-03-14
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);
    }
};
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);
    }
}

}

请帮助我获取相机预览尺寸的场景。

共有1个答案

纪正德
2023-03-14

我得到了一个设备的小表面视图。其实我想要全屏摄像头预览扫描二维码

>

  • 如果您是说相机没有占据整个屏幕,那么请尝试更改

    android:layout_width="match_parent"
    android:layout_height="match_parent"
    

    surfaceviewparent_layout

    mScannerView = new ZBarScannerView(this) {
            /**
             * this will alter the scanning area
             **/
            @Override
            protected IViewFinder createViewFinderView(Context context) {
                return new CustomViewFinderView(context);
            } 
        };
    
    
    
    private class CustomViewFinderView extends ViewFinderView {
        Context context;
    
        public CustomViewFinderView(Context context) {
            super(context);
            this.context = context;
            setLaserEnabled(true);
        }
    
        @Override
        public void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if (getFramingRect() != null) {
                updateFrameRect();
                setBorderColor(ContextCompat.getColor(context, R.color.colorPrimary));
            }
        }
    
        private void updateFrameRect() {
            Point viewResolution = new Point(this.getWidth(), this.getHeight());
            int height = (int) ((float) this.getHeight());
            int width = (int) ((float) this.getWidth());
    
            int leftOffset = (viewResolution.x - width) / 2;
            int topOffset = (viewResolution.y - height) / 2;
    
            getFramingRect().left = leftOffset;
            getFramingRect().top = topOffset;
            getFramingRect().right = leftOffset + width;
            getFramingRect().bottom = topOffset + height;
        }
    }
    

  •  类似资料:
    • 盒区扫描。我如何使它更小的方框面积或调整大小?抱歉,我还没有修改的代码,因为我卡住了如何调整它的大小。

    • 我有一个问题,让我的PhoneGap 3.2.0应用程序在Mac上编译,当Zbar条形码扫描器插件实现。如果我部署到该设备,它将在XCode内编译,但如果部署到模拟设备,它会给出错误: ld:警告:忽略文件/users/cordova/myapp/platforms/ios/zbarsdk/libzbar.a,文件/users/cordova/myapp/platforms/ios/zbarsdk

    • 我想用iPhone摄像头测试我的条形码扫描器。 我正在使用ZBar SDK为我的条形码扫描。 有谁能告诉我如何选择一个条形码图像和扫描它使用模拟器吗? 多谢了。

    • 本文向大家介绍iOS中使用ZBar扫描二维码自定义扫描界面功能,包括了iOS中使用ZBar扫描二维码自定义扫描界面功能的使用技巧和注意事项,需要的朋友参考一下 之前在Android中使用过ZXing识别二维码,ZXing也有对应的iOS版本,经过了解,ZBar也是一个常用的二维码识别软件,并分别提供了iOS和Android的SDK可供使用,最终我选择了ZBar进行二维码识别,它的注释清晰,便于使用

    • 我在我的第一个java程序中扫描用户输入时遇到了一些麻烦。当我编译并运行它时,会立即提示输入(即命令行停止并闪烁)。当我输入任何东西时,第一行被打印出来,要求我输入一个整数。然后打印第二行,并提示我输入另一个值。 这个程序的输出是我输入的前两个值。这很难解释,但它基本上要求3个输入值,只使用两个。

    • 我一直在努力在Android上制作我的自定义相机活动,但当旋转相机时,表面视图的纵横比会变得混乱。 在我的oncreate for the activity中,我设置了framelayout,它保存了显示相机参数的曲面视图。 然后,在曲面视图中,我设置要显示的相机参数 您可以看到,当手机旋转时,乐高男会变得更高、更瘦: 如何确保相机视图的纵横比正确?