출처 : http://blog.naver.com/airwindtree/220255139786



zxing 2.3이하에서만 가능하다.

zxing 3.1.0 에서 안되더라...


A4용지 를 가로로 놓고

카메라 또한 가로로 놓고 찍는것을 원칙으로 하겠다.







소스 있는 그대로 실행시켜서 바코드 스캐너를 실행하면 위와 같다.


 

1. AndroidManifest.xml

     <activity android:name="com.google.zxing.client.android.CaptureActivity"
              android:screenOrientation="landscape"
              android:clearTaskOnLaunch="true"
              android:stateNotNeeded="true"
              android:configChanges="orientation|keyboardHidden"
              android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
              android:windowSoftInputMode="stateAlwaysHidden">

 

--------------------------------------------

* 변경부분

* 이부분을 android:screenOrientation="portrait" 로 변경

 

1. 변경후 실행화면

 


 메뉴, 바코드 인식 선이 세로로 되었다.


 사진상에서는 이상한점을

 느끼지 못할지 모르겠지만,


 직접 실행해 보면

 가로로 상태인데 카메라가

 세로로 변경되어서 나온다


 실제 화상과

 카메라 화상이 90도가 꺽여있는 상태이다.

 

  내가 원하는 카메라 상태

왼쪽 

                  |

                  |

                  |

 아래 <------------>위

                  |

                  |

                  |

               오른쪽


 

 

 

 

2. src/com.google.zxing.client.android.camera/CameraConfigurationManager.java

   void setDesiredCameraParameters(Camera cameraboolean safeMode) {
    camera.setDisplayOrientation(90); //<---  코드를 추가한다

    Camera.Parameters parameters = camera.getParameters();

    if (parameters == null) {
      Log.w(TAG, "Device error: no camera parameters are available. Proceeding without configuration.");
      return;
    }

 

--------------------------------------------

* 변경부분

   코드 추가 (빨간색 코드)

 

2. 변경후 실행화면

 


내가 원하는데로 화상 또한 돌아갔다.



그런데...

현 문제 :  바코드 인식이 세로일때 안되고, 가로일때 인식이 된다

              가로일때 인식해도 결과값이 가로로 나오면서 화면이 깨진다.


세로일때 인식시킬 수 있게 바꿔보자


3. src/com.google.zxing.client.android.camera/CameraManager.java

  private static final int MAX_FRAME_WIDTH = 1200; // = 5/8 * 1920 , 1920/2 : 960
  private static final int MAX_FRAME_HEIGHT = 675; // = 5/8 * 1080, 1080/2 :540

  /**
   * Like {@link #getFramingRect} but coordinates are in terms of the preview frame, not UI / screen.
    * @return {@link Rect} expressing barcode scan area in terms of the preview size

      {#getFramingRect을 @link}하지만 좌표는 미리보기 프레임이 아닌 UI / 화면의 측면에있는 것처럼.

        미리보기 크기의 측면에서 @return {@link RECT} 표현 바코드 스캔 영역
   */
  public synchronized Rect getFramingRectInPreview() {
    if (framingRectInPreview == null) {
      Rect framingRect = getFramingRect();
      if (framingRect == null) {
        return null;
      }
      Rect rect new Rect(framingRect);
      Point cameraResolution configManager.getCameraResolution();
      Point screenResolution configManager.getScreenResolution();
      if (cameraResolution == null || screenResolution == null) {
        // Called early, before init even finished

            초기화도 완성하기 전에, 초기 호출
        return null;
      }


      rect.left rect.left cameraResolution.screenResolution.x;
      rect.right rect.right cameraResolution.screenResolution.x;
      rect.top rect.top cameraResolution.screenResolution.y;
      rect.bottom rect.bottom cameraResolution.screenResolution.y;


      framingRectInPreview = rect;
    }
    return framingRectInPreview;
  }

 

--------------------------------------------

* 변경부분

   위 코드를 이 코드로 변경

      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. 변경후 실행화면

 

여전히 가로일때 인식된다.



결과 화면이 세로로 정상적으로 잘 나온다.

 


4. src/com.google.zxing.client.android/DecodeHandler.java

   /**
   * Decode the data within the viewfinder rectangle, and time how long it took. For efficiency,reuse the same reader objects from one decode to the next.
   *
   * @param data   The YUV preview frame.
   * @param width  The width of the preview frame.
   * @param height The height of the preview frame.

    그것이 걸린 시간 뷰 파인더 사각형 내에서 데이터 및 시간을 디코딩. 효율성을 위해, 하나의 디코드에서 다음에 같은 리더 객체를 다시 사용합니다.

   * @param data   YUV 미리보기 프레임

   * @param width  프리뷰 프레임의 폭

   * @param height  미리보기 프레임의 높이입니다.   
   */
  private void decode(byte[] dataint widthint height) {
  //----------------------------------------------------------------

 //코드 추가

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

    data=portraitData;

  // 회전한 데이터를 buildLuminanceSource 에서 사용 해야 함   * data로 되어있는것 portraitData 로 변경

  //----------------------------------------------------------------

    long start = System.currentTimeMillis();
    Result rawResult null;
    PlanarYUVLuminanceSource source activity.getCameraManager().buildLuminanceSource( datawidthheight);

    if (source != null) {
      BinaryBitmap bitmap new BinaryBitmap(new HybridBinarizer(source));
      try {
              rawResult = multiFormatReader.decodeWithState(bitmap);
            } catch (ReaderException re) {
        // continue
            } finally {
               multiFormatReader.reset();
            }
    }

 

    Handler handler activity.getHandler();
    if (rawResult != null) {
      // Don't log the barcode contents for security.

      // 보안을 위해 바코드 내용을 기록하지 않습니다.
      long end = System.currentTimeMillis();
      Log.d(TAG, "Found barcode in " + (end start) + " ms");


      if (handler != null) {
        Message message = Message.obtain(handler, R.id.decode_succeededrawResult);
        Bundle bundle new Bundle();
        bundleThumbnail(sourcebundle);        
        message.setData(bundle);
        message.sendToTarget();
        }
    } else {
      if (handler != null) {
        Message message = Message.obtain(handler, R.id.decode_failed);
        message.sendToTarget();
      }
    }
  }

 

 --------------------------------------------

 * 변경부분

    빨간 부분 코드 추가

 

 

 

4. 변경후 실행화면


세로로 바코드 스캔이 인식이 된다.


결과물이 잘 나온다.




- 사각형 위치 조정

 CameraManager.java

 public final class CameraManager {
   private static final int MAX_FRAME_WIDTH = 960; // 1920/2
private static final int MAX_FRAME_HEIGHT= 540; // = 1080/2


 public synchronized Rect getFramingRect() {
     int topOffset = (screenResolution.y - height) / 9; // 2->10 세로 수정
 }

 private static int findDesiredDimensionInRange(int resolution, int hardMin, int hardMax) {
 int dim = 7 * resolution / 10; // Target 50% of each dimension
 }




."끝"











Posted by motolies

댓글을 달아 주세요