Android Camera结合Zxing优化扫码

先上个图:

由于之前集成的zxing扫塑料上面的码不太好扫,决定优化。Zxing的解码我们优化不了了,经过测试,是因为亮度不够,所以最终选择在灯光和放大焦距完成了最终的优化。
设置模式只需要几行代码即可:

//得到Camera对象
Camera camera = CameraManager.get().getCamera();
Camera.Parameters parameters = camera.getParameters();
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
//设置给相机
camera.setParameters(parameters);

我们来看看有哪些模式可以设置,基本包含了所有的设置:

//1、设置相机滤镜模式
    public synchronized void changeEffect(final Button btn){
        PopupMenu pop = new PopupMenu(context, btn);
        pop.getMenuInflater().inflate(R.menu.menu, pop.getMenu());
        pop.show();
        pop.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                int i = item.getItemId();
                if (i == R.id.effect_none) {
                    parameters.setColorEffect(Camera.Parameters.EFFECT_NONE);
                }
                else if (i == R.id.effect_mono) {
                    parameters.setColorEffect(Camera.Parameters.EFFECT_MONO);
                }
                else if (i == R.id.effect_negative) {
                    parameters.setColorEffect(Camera.Parameters.EFFECT_NEGATIVE);
                }
                else if (i == R.id.effect_solarize) {
                    parameters.setColorEffect(Camera.Parameters.EFFECT_SOLARIZE);
                }
                else if (i == R.id.effect_sepia) {
                    parameters.setColorEffect(Camera.Parameters.EFFECT_SEPIA);
                }
                else if (i == R.id.effect_posterize) {
                    parameters.setColorEffect(Camera.Parameters.EFFECT_POSTERIZE);
                }
                else if (i == R.id.effect_whiteboard) {
                    parameters.setColorEffect(Camera.Parameters.EFFECT_WHITEBOARD);
                }
                else if (i == R.id.effect_blackboard) {
                    parameters.setColorEffect(Camera.Parameters.EFFECT_BLACKBOARD);
                }
                else if (i == R.id.effect_aqua) {
                    parameters.setColorEffect(Camera.Parameters.EFFECT_AQUA);
                }
                btn.setText(item.getTitle());
                setParameters(camera, parameters);
                return false;

            }

        });

    }

    //2、设置相机对焦模式
    public synchronized void changeFocus(final Button btn){
        PopupMenu pop = new PopupMenu(context, btn);
        pop.getMenuInflater().inflate(R.menu.menu_focus, pop.getMenu());
        pop.show();
        pop.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                int i = item.getItemId();
                if (i == R.id.focus_mode_auto) {
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                }
                else if (i == R.id.focus_mode_infinity) {
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
                }
                else if (i == R.id.focus_mode_macro) {
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);
                }
                else if (i == R.id.focus_mode_fixed) {
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED);
                }
                else if (i == R.id.focus_mode_edof) {
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_EDOF);
                }
                else if (i == R.id.focus_mode_continuous_video) {
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
                }
                else if (i == R.id.focus_mode_continuous_picture) {
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                }
                btn.setText(item.getTitle());
                setParameters(camera, parameters);
                return false;
            }
        });
    }

    //3、设置相机闪光灯模式
    public synchronized void changeFlash(final Button btn){
        PopupMenu pop = new PopupMenu(context, btn);
        pop.getMenuInflater().inflate(R.menu.menu_flash, pop.getMenu());
        pop.show();
        pop.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                int i = item.getItemId();
                if (i == R.id.flash_mode_auto) {
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
                }
                else if (i == R.id.flash_mode_on) {
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
                }
                else if (i == R.id.flash_mode_off) {
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                }
                else if (i == R.id.flash_mode_red_eye) {
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_RED_EYE);
                }
                else if (i == R.id.flash_mode_torch) {
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                }
                btn.setText(item.getTitle());
                setParameters(camera, parameters);
                return false;
            }
        });
    }

    //4、设置相机场景模式
    public synchronized void changeScene(final Button btn){
        final PopupMenu pop = new PopupMenu(context, btn);
        pop.getMenuInflater().inflate(R.menu.menu_scene, pop.getMenu());
        pop.show();
        pop.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                int i = item.getItemId();
                if (i == R.id.scene_mode_action) {
                    parameters.setSceneMode(Camera.Parameters.SCENE_MODE_ACTION);
                }
                else if (i == R.id.scene_mode_auto) {
                    parameters.setSceneMode(Camera.Parameters.SCENE_MODE_AUTO);
                }
                else if (i == R.id.scene_mode_barcode) {
                    parameters.setSceneMode(Camera.Parameters.SCENE_MODE_BARCODE);
                }
                else if (i == R.id.scene_mode_beach) {
                    parameters.setSceneMode(Camera.Parameters.SCENE_MODE_BEACH);
                }
                else if (i == R.id.scene_mode_candlelight) {
                    parameters.setSceneMode(Camera.Parameters.SCENE_MODE_CANDLELIGHT);
                }
                else if (i == R.id.scene_mode_fireworks) {
                    parameters.setSceneMode(Camera.Parameters.SCENE_MODE_FIREWORKS);
                }
                else if (i == R.id.scene_mode_hdr) {
                    parameters.setSceneMode(Camera.Parameters.SCENE_MODE_HDR);
                }
                else if (i == R.id.scene_mode_landscape) {
                    parameters.setSceneMode(Camera.Parameters.SCENE_MODE_LANDSCAPE);
                }
                else if (i == R.id.scene_mode_night) {
                    parameters.setSceneMode(Camera.Parameters.SCENE_MODE_NIGHT);
                }
                else if (i == R.id.scene_mode_night_portrait) {
                    parameters.setSceneMode(Camera.Parameters.SCENE_MODE_NIGHT_PORTRAIT);
                }
                else if (i == R.id.scene_mode_party) {
                    parameters.setSceneMode(Camera.Parameters.SCENE_MODE_PARTY);
                }
                else if (i == R.id.scene_mode_portrait) {
                    parameters.setSceneMode(Camera.Parameters.SCENE_MODE_PORTRAIT);
                }
                else if (i == R.id.scene_mode_snow) {
                    parameters.setSceneMode(Camera.Parameters.SCENE_MODE_SNOW);
                }
                else if (i == R.id.scene_mode_sports) {
                    parameters.setSceneMode(Camera.Parameters.SCENE_MODE_SPORTS);
                }
                else if (i == R.id.scene_mode_steadyphoto) {
                    parameters.setSceneMode(Camera.Parameters.SCENE_MODE_STEADYPHOTO);
                }
                else if (i == R.id.scene_mode_sunset) {
                    parameters.setSceneMode(Camera.Parameters.SCENE_MODE_SUNSET);
                }
                else if (i == R.id.scene_mode_theatre) {
                    parameters.setSceneMode(Camera.Parameters.SCENE_MODE_THEATRE);
                }
                btn.setText(item.getTitle());
                setParameters(camera, parameters);
                return false;
            }
        });
    }


    //4、设置支持的防牛顿环设置
    public synchronized void changeAntibanding(final Button btn){
        PopupMenu pop = new PopupMenu(context, btn);
        pop.getMenuInflater().inflate(R.menu.menu_antibanding, pop.getMenu());
        pop.show();
        pop.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                int i = item.getItemId();
                if (i == R.id.antibanding_auto) {
                    parameters.setAntibanding(Camera.Parameters.ANTIBANDING_AUTO);
                }
                else if (i == R.id.antibanding_off) {
                    parameters.setAntibanding(Camera.Parameters.ANTIBANDING_OFF);
                }
                else if (i == R.id.antibanding_50hz) {
                    parameters.setAntibanding(Camera.Parameters.ANTIBANDING_50HZ);
                }
                else if (i == R.id.antibanding_60hz) {
                    parameters.setAntibanding(Camera.Parameters.ANTIBANDING_60HZ);
                }
                btn.setText(item.getTitle());
                setParameters(camera, parameters);
                return false;
            }
        });
    }

    //5、设置白平衡
    public synchronized void changeWhite(final Button btn){
        PopupMenu pop = new PopupMenu(context, btn);
        pop.getMenuInflater().inflate(R.menu.menu_white, pop.getMenu());
        pop.show();
        pop.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                int i = item.getItemId();
                if (i == R.id.white_balance_auto) {
                    parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
                }
                else if (i == R.id.white_balance_cloudy_daylight) {
                    parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT);
                }
                else if (i == R.id.white_balance_daylight) {
                    parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_DAYLIGHT);
                }
                else if (i == R.id.white_balance_fluorescent) {
                    parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_FLUORESCENT);
                }
                else if (i == R.id.white_balance_incandescent) {
                    parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_INCANDESCENT);
                }
                else if (i == R.id.white_balance_shade) {
                    parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_SHADE);
                }
                else if (i == R.id.white_balance_twilight) {
                    parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_TWILIGHT);
                }
                else if (i == R.id.white_balance_warm_fluorescent) {
                    parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT);
                }
                btn.setText(item.getTitle());
                setParameters(camera, parameters);
                return false;
            }
        });
    }

    //6、设置相机放大(焦距)
    public synchronized void changeZoom(final Button btn){
        PopupMenu pop = new PopupMenu(context, btn);
        pop.getMenuInflater().inflate(R.menu.menu_zoom, pop.getMenu());
        pop.show();
        pop.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                int i = item.getItemId();
                if (i == R.id.zoom20) {
                    parameters.setZoom(20);
                }
                else if (i == R.id.zoom40) {
                    parameters.setZoom(40);
                }
                else if (i == R.id.zoom60) {
                    parameters.setZoom(60);
                }
                else if (i == R.id.zoom78) {
                    parameters.setZoom(78);
                }
                else if (i == R.id.zoom2) {
                    parameters.setZoom(2);
                }
                btn.setText(item.getTitle());
                setParameters(camera, parameters);
                return false;
            }
        });
    }





    public static synchronized void setParameters(Camera camera, Camera.Parameters parameters){
        camera.setParameters(parameters);
    }

具体参数的意思请参照:
http://blog.csdn.net/aiqing0119/article/details/27680137

下面说说我的问题是怎么解决的:
经常测试,发现设置parameters.setZoom(20);再加上闪光灯比较好扫,但是我发现经常会扫着扫着就模糊了,所以决定每秒设置一次焦点对焦模式,发现有所改善。
代码如下:

//----------------------------设置最佳默认扫码配置-------------------------------------------------


    private void setDefaultSetting() {
        parameters = camera.getParameters();
        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
        parameters.setZoom(20);
        setCameras();
        setFocus();
    }

    private synchronized void setCameras() {
        camera.setParameters(parameters);
    }


    private void setFocus() {
        focusHandler.postDelayed(runnable, 1000);
    }


    final Handler focusHandler = new Handler();
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            //每隔1秒对一次焦点
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
            setCameras();
            focusHandler.postDelayed(this, 1000);
        }
    };

    private void removeTask() {
        if (null != focusHandler && null != runnable) {
            focusHandler.removeCallbacks(runnable);
        }
    }

附加一个连续扫码的功能:

public void handleDecode(Result result, Bitmap barcode) {
    inactivityTimer.onActivity();
    playBeepSoundAndVibrate();

    if (result == null || TextUtils.isEmpty(result.getText())) {
        if (analyzeCallback != null) {
            analyzeCallback.onAnalyzeFailed();
        }
    } else {
        if (analyzeCallback != null) {
            analyzeCallback.onAnalyzeSuccess(barcode, result.getText());
        }
    }
    continuePreview();
}

//连续扫码
private void continuePreview(){
    SurfaceHolder surfaceHolder = surfaceView.getHolder();
    initCamera(surfaceHolder);
    if (handler != null){
        handler.restartPreviewAndDecode();
    }
}

最终提升了一定的扫码率,不过最终确定是码本身就有一些问题。

另外,在这个文章里面看到可以修改对比度、亮度、怪我技术不足,没能设置,有大神看到可否指导一二。
http://blog.csdn.net/fireness/article/details/49684493

public String getEdgeMode()//获取锐度模式
public void setEdgeMode(String value)//设置锐度模式
public List<String> getSupportedEdgeMode()//获取支持的所有锐度模式
public String getHueMode()//色度
public void setHueMode(String value)
public List<String> getSupportedHueMode()
public String getSaturationMode()//饱和度
public void setSaturationMode(String value)
public List<String> getSupportedSaturationMode()
public String getBrightnessMode()//亮度
public void setBrightnessMode(String value)
public List<String> getSupportedBrightnessMode()
public String getContrastMode()//对比度
public void setContrastMode(String value)
public List<String> getSupportedContrastMode()

引用zxing源码:
https://github.com/yipianfengye/android-zxingLibrary
本项目源码:

https://github.com/MrXiong/android_zxingLibrary_zx

你可能感兴趣的:(android)