ZXing條碼掃描-豎屏解決方案

jopen 10年前發布 | 53K 次閱讀 Android開發 移動開發 zxing

寫在前面的話

感謝ZXing團隊,項目下載地址:https://github.com/zxing/zxing,項目下載后,Android條碼掃描主要用到三個模塊:android,android-core,core。zxing項目解壓后目錄結構如圖所示:
zxing目錄結構
android是ZXing提供的條碼掃描器apk客戶端源碼,android-core和core是需要的類庫。本文提供的zxing豎屏掃描解決方案采用的android版本號versionName為4.7.4,versionCode為104,zxing類庫版本號為3.2.0,理論上4.7.x通用。
zxing類庫無法直接導入Eclipse,筆者采用的方式是新建工程ZXLib后,將android-core,core中的java代碼拷貝進去,注意android-core中只有一個CameraConfigurationUtils.java類,主要類庫是core,CameraConfigurationUtils.java的包名:com.google.zxing.client.android.camera,拷貝進去時需要與core類庫的相應包名對應,最后別忘記將這個工程設置為library。
友情提示:本文提供解決方案,類庫源碼不進行任何修改,以下提到的修改部分均為客戶端源碼。</span>

zxing如何豎屏掃描

將zxing源碼android導入Eclipse后,關聯ZXLib,也就是剛才新建的ZXing類庫。運行后可直接使用條碼掃描功能,可是默認是橫屏,筆者項目中需要使用豎屏方式掃描,于是需要將zxing條碼掃描改成豎屏方式掃描。步驟寫的有些細致,請耐心閱讀。

第一步:修改AndroidManifest工程清單,AndroidManifest中CaptureActivity的screenOrientation屬性改為portrait:


<activity android:name=".CaptureActivity"
              android:screenOrientation="portrait"
              android:clearTaskOnLaunch="true"
              android:stateNotNeeded="true"
              android:theme="@style/CaptureTheme"
              android:windowSoftInputMode="stateAlwaysHidden">



第二步:刪除CaptureActivity中把onResume方法中的無用代碼:


//    if (prefs.getBoolean(PreferencesActivity.KEY_DISABLE_AUTO_ORIENTATION, true)) {
//      setRequestedOrientation(getCurrentOrientation());
//    } else {
//      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
//    }

第三步:在CaptureActivity中把onCreate方法結尾處添加代碼:



if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    } else {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }
經過前三步,條碼掃描器已經豎屏了,相信很多人也改到這里就出現問題了,zxing條碼掃描器相機預覽方向旋轉了90度,并且容易拉伸,我們需要糾正相機預覽方向。



第四步:在CameraConfigurationManager的setDesiredCameraParameters方法中添加代碼:


camera.setDisplayOrientation(90);//add 這句代碼作用是旋轉鏡頭90度,使相機預覽方向正確顯示
camera.setParameters(parameters);
相機預覽正常了,也沒有拉伸,可是二維碼識別卻慢了許多,并且一維條碼識別不出來,需要橫屏掃描才可以識別,而且條碼成像仍然是橫向的,下面步驟將解決這個問題。



第五步:修改CameraManager中getFramingRectInPreview方法:


//      rect.left = rect.left * cameraResolution.x / screenResolution.x;
//      rect.right = rect.right * cameraResolution.x / screenResolution.x;
//      rect.top = rect.top * cameraResolution.y / screenResolution.y;
//      rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y;

        rect.left = rect.left * cameraResolution.y / screenResolution.x;
        rect.right = rect.right * cameraResolution.y / screenResolution.x;
        rect.top = rect.top * cameraResolution.x / screenResolution.y;
        rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;

第六步:修改DecodeHandler中的decode(byte[] data, int width, int height)方法:



PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height);
前添加代碼



   byte[] rotatedData = new byte[data.length];
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++)
            rotatedData[x * height + height - y - 1] = data[x + y * width];
    }
    int tmp = width;
    width = height;
    height = tmp;
    data = rotatedData;


結束語

只進行了第五步,而沒有第六步,會在zxing類庫的CameraConfigurationUtils 283行拋出異常



IllegalStateException("Parameters contained no preview size!");
如果只進行了第六步,而沒有第五步,則無法正常識別條碼。


好了,經過以上六步,zxing條碼掃描器已經可以正常豎屏掃描了,剩下的工作就是精簡代碼了,祝大家順利完成項目。
轉載請注明作者xiong_it和原文出處:http://blog.csdn.net/xiong_it/article/details/46983293,謝謝!

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!