如何更改扫描Zbar的区域? [英] How to change area of scan Zbar?

查看:1996
本文介绍了如何更改扫描Zbar的区域?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想换相机扫描的区域。现在我把图像扫描大如设备的屏幕。我试图裁剪图像分析。所以只是preVIEW中心将源代码进行扫描。是否有任何选项来设置捕获preVIEW更小或创建从byte []数据位图和作物也变得越来越小区域的唯一途径?我想读一些有关它但Zbar Android的文档是非常差(以容比较IOS)。

图片浏览: http://postimg.org/image/4wk4u0mln/

MainActivity

 公共类MainActivity扩展活动
{
    私人相机mCamera;
    私人上下文的背景下;
    私人相机preVIEW米preVIEW;
    私人处理器autoFocusHandler;

    TextView的scanText;
    按钮scanButton;

    图象扫描仪;
    私人PowerManager.WakeLock WL;

    私人布尔吧codeScanned = FALSE;
    私人布尔previewing = TRUE;

    静态{
        的System.loadLibrary(的iconv);
    }

    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);



        的setContentView(R.layout.activity_main);

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        autoFocusHandler =新的处理程序();
        mCamera = getCameraInstance();


        上下文= getApplicationContext();

        / *实例吧code扫描* /
        扫描=新的图象扫描();

        scanner.setConfig(0,Config.X_DENSITY,3);
        scanner.setConfig(0,Config.Y_DENSITY,3);

        米preVIEW =新相机preVIEW(这一点,mCamera,previewCb,autoFocusCB);
        的FrameLayout preVIEW =(的FrameLayout)findViewById(R.id.camera preVIEW);
        preview.addView(M preVIEW);

        scanText =(TextView中)findViewById(R.id.scanText);


    }

    @覆盖
    公共无效的onPause(){
        super.onPause();
        releaseCamera();
    }

    @覆盖
    保护无效onResume(){
        // TODO自动生成方法存根

        ONSTART();
    }

    @覆盖
    保护无效的onStop(){
        // TODO自动生成方法存根
        super.onStop();

        完();
    }

    / **一个安全的方式来获取Camera对象的实例。 * /
    公共静态相机getCameraInstance(){
        相机C = NULL;
        尝试 {
            C = Camera.open();
        }赶上(例外五){
        }
        返回℃;
    }

    私人无效releaseCamera(){
        如果(mCamera!= NULL){
            previewing = FALSE;
            mCamera.set previewCallback(空);
            mCamera.release();
            mCamera = NULL;
        }
    }

    私人可运行doAutoFocus =新的Runnable(){
            @覆盖
            公共无效的run(){
                如果(previewing)
                    mCamera.autoFocus(autoFocusCB);
            }
        };

    previewCallback previewCb =新的previewCallback(){
            @覆盖
            在previewFrame(byte []的数据,摄像头摄像头){公共无效
                Camera.Parameters参数= camera.getParameters();
                尺寸尺寸= parameters.get previewSize();
                //这里我们读到拍摄的照片从prieview
                图片吧code =新的图像(size.width,size.height,Y800);

                酒吧code.setData(数据);


                INT结果= scanner.scanImage(巴code);

                如果(结果!= 0){
                    previewing = FALSE;
                    mCamera.set previewCallback(空);


                    mCamera.stop preVIEW();



                    SymbolSet SYMS = scanner.getResults();
                    对于(符号SYM:SYMS){

                    如果(sym.getType()==符号。code128){
                        sym.getData());
                        MediaPlayer的MP = MediaPlayer.create(背景下,R.raw.beep_ok);
                        mp.start();


                    } 其他 {

                        MediaPlayer的MP = MediaPlayer.create(背景下,R.raw.beep_wrong);
                        mp.start();
                    }


                        mCamera.set previewCallback(previewCb);
                        mCamera.start preVIEW();
                        previewing = TRUE;
                        mCamera.autoFocus(autoFocusCB);



                    }
                }
            }
        };

    //模仿连续自动对焦
    AutoFocusCallback autoFocusCB =新AutoFocusCallback(){
            @覆盖
            公共无效onAutoFocus(布尔成功,相机摄像头){
                autoFocusHandler.postDelayed(doAutoFocus,1000);
            }
        };


        //方法裁剪位图的情况下使用
        公共位图scaleCenterCrop(位图​​源,诠释newHeight,诠释newWidth){
            INT sourceWidth = source.getWidth();
            INT sourceHeight = source.getHeight();

            浮xScale等=(浮点)newWidth / sourceWidth;
            浮动yScale =(浮点)newHeight / sourceHeight;
            浮规模= Math.max(xScale等,yScale);

            浮scaledWidth =规模* sourceWidth;
            浮scaledHeight =规模* sourceHeight;

            左浮动=(newWidth  -  scaledWidth)/ 2;
            浮顶=(newHeight  -  scaledHeight)/ 2;

            RectF targetRect =新RectF(左,上,左+ scaledWidth,顶部+ scaledHeight);


            位图DEST = Bitmap.createBitmap(newWidth,newHeight,source.getConfig());
            帆布油画=新的Canvas(DEST);
            canvas.drawBitmap(源,空,targetRect,NULL);

            返回DEST;
        }

}
 

CameraPrieview.java

 公共类相机preVIEW延伸SurfaceView实现SurfaceHolder.Callback {
    私人SurfaceHolder mHolder;
    私人相机mCamera;
    私人previewCallback previewCallback;
    私人AutoFocusCallback autoFocusCallback;

    公共摄像头preVIEW(上下文的背景下,摄像头的摄像头,
                         previewCallback previewCb,
                         AutoFocusCallback autoFocusCb){
        超(上下文);
        mCamera =摄像头;
        previewCallback = previewCb;
        autoFocusCallback = autoFocusCb;

        / *
         *设置相机如果支持连续对焦,否则使用
         *软件自动对焦。仅适用于API级别> = 9。
         * /
        / *
        Camera.Parameters参数= camera.getParameters();
        对于(字符串型F:parameters.getSupportedFocusModes()){
            如果(F == Parameters.FOCUS_MODE_CONTINUOUS_PICTURE){
                mCamera.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                autoFocusCallback = NULL;
                打破;
            }
        }
        * /

        //安装SurfaceHolder.Callback所以我们得到通知时,该
        //下垫面创建和销毁。
        mHolder = getHolder();
        mHolder.addCallback(本);

        //德precated设置,但在Android上之前的版本3.0所需
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @覆盖
    公共无效surfaceCreated(SurfaceHolder持有者){
        //表面有被创建,现在告诉相机在哪里画preVIEW。
        尝试 {
            mCamera.set previewDisplay(保持器);
        }赶上(IOException异常E){
            Log.d(DBG,错误设置摄像头preVIEW:+ e.getMessage());
        }
    }

    @覆盖
    公共无效surfaceDestroyed(SurfaceHolder持有者){
        //摄像机$发布活动p $ PVIEW
    }

    @覆盖
    公共无效surfaceChanged(SurfaceHolder持有人,INT格式,诠释的宽度,高度INT){
        / *
         *如果你的preVIEW可以改变或旋转,在这里采取这些事件的照顾。
         *请务必调整或重新格式化之前停止preVIEW。
         * /
        如果(mHolder.getSurface()== NULL){
          // preVIEW表面不存在
          返回;
        }

        在进行更改之前//停止preVIEW
        尝试 {
            mCamera.stop preVIEW();
        }赶上(例外五){
          //忽略:试图阻止一个不存在的preVIEW
        }

        尝试 {
            //硬code相机表面旋转90度的视角,以配合在纵向活动视图
            mCamera.setDisplayOrientation(90);

            mCamera.set previewDisplay(mHolder);
            mCamera.set previewCallback(previewCallback);
            mCamera.start preVIEW();
            mCamera.autoFocus(autoFocusCallback);
        }赶上(例外五){
            Log.d(DBG,错误启动摄像头preVIEW:+ e.getMessage());
        }
    }
}
 

解决方案

在previewCallback实际上你可以裁剪扫描区域。在上previewFrame方法,调用吧code.setData(),你可以调用后的吧code.setCrop(左,上,宽,高)。以像素为单位的所有测量。
另外,还要确保相对于在preVIEW图像的大小,而不是设备的屏幕大小设置裁剪尺寸。

注意的:请确保x轴始终是,即使你定位手机在纵向模式下最长边。 请参考下面的图片为更好地理解参数。

这个解决方案是专门针对zbar为Android。

I want to change the area of camera scan. Now I take image to scan as big as screen of device. I'm trying to crop image to analyze. So just the center of preview will be source to scan. Is there any option to set captured preview to be smaller or creating Bitmap from byte[] data and crop it is the only way to get smaller area? I was trying to read something about it but documentation for Zbar Android is very poor (compareing to iOs).

Picture here: http://postimg.org/image/4wk4u0mln/

MainActivity

public class MainActivity extends Activity
{
    private Camera mCamera;
    private Context context;
    private CameraPreview mPreview;
    private Handler autoFocusHandler;

    TextView scanText;
    Button scanButton;

    ImageScanner scanner;
    private PowerManager.WakeLock wl;

    private boolean barcodeScanned = false;
    private boolean previewing = true;

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

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



        setContentView(R.layout.activity_main);

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        autoFocusHandler = new Handler();
        mCamera = getCameraInstance();


        context = getApplicationContext();

        /* Instance barcode scanner */
        scanner = new ImageScanner();

        scanner.setConfig(0, Config.X_DENSITY, 3);
        scanner.setConfig(0, Config.Y_DENSITY, 3);

        mPreview = new CameraPreview(this, mCamera, previewCb, autoFocusCB);
        FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview);
        preview.addView(mPreview);

        scanText = (TextView)findViewById(R.id.scanText);


    }

    @Override
    public void onPause() {
        super.onPause();
        releaseCamera();
    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub

        onStart();
    }

    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        super.onStop();

        finish();
    }

    /** A safe way to get an instance of the Camera object. */
    public static Camera getCameraInstance(){
        Camera c = null;
        try {
            c = Camera.open();
        } catch (Exception e){
        }
        return c;
    }

    private void releaseCamera() {
        if (mCamera != null) {
            previewing = false;
            mCamera.setPreviewCallback(null);
            mCamera.release();
            mCamera = null;
        }
    }

    private Runnable doAutoFocus = new Runnable() {
            @Override
            public void run() {
                if (previewing)
                    mCamera.autoFocus(autoFocusCB);
            }
        };

    PreviewCallback previewCb = new PreviewCallback() {
            @Override
            public void onPreviewFrame(byte[] data, Camera camera) {
                Camera.Parameters parameters = camera.getParameters();
                Size size = parameters.getPreviewSize();
                //HERE we read taken picture from prieview
                Image barcode = new Image(size.width, size.height, "Y800");

                barcode.setData(data);


                int result = scanner.scanImage(barcode);

                if (result != 0) {
                    previewing = false;
                    mCamera.setPreviewCallback(null);


                    mCamera.stopPreview();



                    SymbolSet syms = scanner.getResults();
                    for (Symbol sym : syms) {

                    if (sym.getType() == Symbol.CODE128) {
                        sym.getData());
                        MediaPlayer mp = MediaPlayer.create(context, R.raw.beep_ok); 
                        mp.start();


                    } else {

                        MediaPlayer mp = MediaPlayer.create(context, R.raw.beep_wrong); 
                        mp.start();
                    }


                        mCamera.setPreviewCallback(previewCb);
                        mCamera.startPreview();
                        previewing = true;
                        mCamera.autoFocus(autoFocusCB);



                    }
                }
            }
        };

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


        //Method to crop Bitmap in case of use
        public Bitmap scaleCenterCrop(Bitmap source, int newHeight, int newWidth) {
            int sourceWidth = source.getWidth();
            int sourceHeight = source.getHeight();

            float xScale = (float) newWidth / sourceWidth;
            float yScale = (float) newHeight / sourceHeight;
            float scale = Math.max(xScale, yScale);

            float scaledWidth = scale * sourceWidth;
            float scaledHeight = scale * sourceHeight;

            float left = (newWidth - scaledWidth) / 2;
            float top = (newHeight - scaledHeight) / 2;

            RectF targetRect = new RectF(left, top, left + scaledWidth, top + scaledHeight);


            Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, source.getConfig());
            Canvas canvas = new Canvas(dest);
            canvas.drawBitmap(source, null, targetRect, null);

            return dest;
        }

}

CameraPrieview.java

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private Camera mCamera;
    private PreviewCallback previewCallback;
    private AutoFocusCallback autoFocusCallback;

    public CameraPreview(Context context, Camera camera,
                         PreviewCallback previewCb,
                         AutoFocusCallback autoFocusCb) {
        super(context);
        mCamera = camera;
        previewCallback = previewCb;
        autoFocusCallback = autoFocusCb;

        /* 
         * Set camera to continuous focus if supported, otherwise use
         * software auto-focus. Only works for API level >=9.
         */
        /*
        Camera.Parameters parameters = camera.getParameters();
        for (String f : parameters.getSupportedFocusModes()) {
            if (f == Parameters.FOCUS_MODE_CONTINUOUS_PICTURE) {
                mCamera.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                autoFocusCallback = null;
                break;
            }
        }
        */

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

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

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

    @Override
    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
        }

        try {
            // Hard code camera surface rotation 90 degs to match Activity view in portrait
            mCamera.setDisplayOrientation(90);

            mCamera.setPreviewDisplay(mHolder);
            mCamera.setPreviewCallback(previewCallback);
            mCamera.startPreview();
            mCamera.autoFocus(autoFocusCallback);
        } catch (Exception e){
            Log.d("DBG", "Error starting camera preview: " + e.getMessage());
        }
    }
}

解决方案

In the PreviewCallback you can actually crop the scanning area. In the onPreviewFrame method, after calling barcode.setData() you can call barcode.setCrop(left,top,width,height). All measurements in pixels.
Also make sure to set the crop size with respect to the preview image size and not the device screen size.

Note: Please make sure that the x-axis is always the longest side even though you orient the phone in portrait mode. Please refer below Image for better understanding of the arguments.

This solution is specific to zbar for android.

这篇关于如何更改扫描Zbar的区域?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆