zxing橫屏改爲豎屏識別,多次掃描,以及存在的攝像拉伸的問題

摘自http://www.cnblogs.com/moka/archive/2013/05/24/3096937.html

按照以上做法,可以實現。

使用簡化版可以免去許多不必要的代碼,方便學習研究,更好定位核心功能。

如果你調試成功後,就可以着手修改將其變爲豎屏識別了。

第1步:

在AndroidManifest中將CaptureActivity的screenOrientation屬性做如下修改:

android:screenOrientation="portrait" 

 

第2步:

我們要把攝像頭預覽景調爲豎向

CameraConfigurationManager類中的setDesiredCameraParameters()方法中添加如下代碼:

// 使攝像頭旋轉90度
    setDisplayOrientation(camera, 90);

然後在CameraConfigurationManager類的最後添加setDisplayOrientation()方法:

/*改變照相機成像的方向的方法*/
  protected void setDisplayOrientation(Camera camera, int angle) {
      Method downPolymorphic = null;        
      try {
        downPolymorphic = camera.getClass().getMethod("setDisplayOrientation", new Class[] { int.class });
        if (downPolymorphic != null)     
              downPolymorphic.invoke(camera, new Object[]{angle});        
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }

  }

 

最後在CameraConfigurationManager中的initFromCameraParameters()方法的Log.d(TAG, "Screen resolution: " + screenResolution);句後面添加如下代碼,這段代碼是爲了解決攝像頭豎過來後圖像拉伸的問題:

//爲豎屏添加
    Point screenResolutionForCamera = new Point();
    screenResolutionForCamera.x = screenResolution.x;
    screenResolutionForCamera.y = screenResolution.y;
    if (screenResolution.x < screenResolution.y) {
        screenResolutionForCamera.x = screenResolution.y;
        screenResolutionForCamera.y = screenResolution.x;
    }
    // 下句第二參數要根據豎屏修改
    cameraResolution = getCameraResolution(parameters, screenResolutionForCamera);

 

第3步:

CameranManager類中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;   

 

第4步:

PlanarYUVLuminanceSource類中的getRow()方法爲識別條形碼部分,

getMatrix()方法爲識別二維碼部分

renderCroppedGreyscaleBitmap()方法爲生成獲取的碼圖部分

將getRow()中的:

int offset = (y + top) * dataWidth + left;

getMatrix()中的:

int inputOffset = top * dataWidth + left;
inputOffset += dataWidth;

renderCroppedGreyscaleBitmap()中的:

int inputOffset = top * dataWidth + left;
inputOffset += dataWidth;

這些語句中dataWidth全部替換爲dataHeight

同時將PlanarYUVLuminanceSource構造方法中:

if (left + width > dataWidth || top + height > dataHeight) {
      throw new IllegalArgumentException("Crop rectangle does not fit within image data.");
    }

dataWidth與dateHeight中互換位置即可。

此時,你的程序豎屏識別碼圖應該沒有任何問題了。至於取景框的樣式,大家可以在自定義的ViewfinderView中修改成自己喜歡的樣式。


——————————————————————————————

測試,可以豎屏,但是取景還是得橫着來。

http://blog.csdn.net/sunmanzth/article/details/6860157  轉摘這篇

解決方法:

1.在DecodeHandler.java中,修改decode方法
  PlanarYUVLuminanceSource source = CameraManager.get().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; // Here we are swapping, that's the difference to #11
    width = height;
    height = tmp;
    
    PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(rotatedData, width, height);

2.在CameraManager.java中,註釋代碼:
            // 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;

3.在CameraConfigurationManager.java中,在setDesiredCameraParameters方法中添加一句
  camera.setDisplayOrientation(90);

4.在AndroidManifest.xml中,把Activity的屬性android:screenOrientation="landscape"
改爲
  android:screenOrientation="portrait"

編譯運行即可!


參考:

http://code.google.com/p/zxing/issues/detail?id=178#c46


代碼:

https://github.com/pplante/zxing-android

————————

按照下篇的解決方案,成功解決問題。

實現zxing多次掃描問題:

private void continuePreview()

 {
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
        initCamera(surfaceHolder);
        if (handler != null)
            handler.restartPreviewAndDecode();  
 }

CaptureActivityHandler中restartPreviewAndDecode屬性由private 設置成public

——————————————————————————————

掃描二維碼圖片時候,正方形的二維碼圖片,顯示會發現變拉長、拉伸。

找着的解決途徑如下:

http://www.apkbus.com/android-94078-1-1.html

更改CameraConfigurationManager.java文件

在 Log.d(TAG, "Screen resolution: " + screenResolution);這句之後增加
Point screenResolutionForCamera = new Point();
        screenResolutionForCamera.x = screenResolution.x;
        screenResolutionForCamera.y = screenResolution.y;
        // preview size is always something like 480*320, other 320*480
        if (screenResolution.x < screenResolution.y) {
        screenResolutionForCamera.x = screenResolution.y;
        screenResolutionForCamera.y = screenResolution.x;
        }
再更改cameraResolution = getCameraResolution(parameters, screenResolution);爲cameraResolution = getCameraResolution(parameters, screenResolutionForCamera);

PS:有時間一定要讀zxing源碼的。

發佈了30 篇原創文章 · 獲贊 7 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章