1. 程式人生 > >Android Camera結合Zxing優化掃碼

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

下面說說我的問題是怎麼解決的:
經常測試,發現設定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();
    }
}

最終提升了一定的掃位元速率,不過最終確定是碼本身就有一些問題。

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()