【问题标题】:Zxing Camera in Portrait mode on AndroidZxing 相机在 Android 上的人像模式
【发布时间】:2013-04-27 13:38:29
【问题描述】:

我想在Zxing 的相机上显示portrait 方向。

如何做到这一点?

【问题讨论】:

标签: android zxing landscape-portrait


【解决方案1】:

这是它的工作原理。

第 1 步:在 decode(byte[] data, int width, int height)

中添加以下行以在 buildLuminanceSource(..) 之前旋转数据

DecodeHandler.java:

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;

PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(rotatedData, width, height);

第二步:修改getFramingRectInPreview()

CameraManager.java

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 步:在 initFromCameraParameters(...) 中禁用横向模式检查

CameraConfigurationManager.java

//remove the following
if (width < height) {
  Log.i(TAG, "Display reports portrait orientation; assuming this is incorrect");
  int temp = width;
  width = height;
  height = temp;
}

第 4 步:添加以下行以在setDesiredCameraParameters(...) 中旋转相机

CameraConfigurationManager.java

camera.setDisplayOrientation(90);

第 5 步:不要忘记将活动方向设置为纵向。即:清单

【讨论】:

  • 这个不错!尽管您要从仅支持横向变为仅支持纵向,而不是两者兼而有之。这也不适用于前置摄像头或倒置的纵向。
  • 此异常显示致命异常:线程 9 java.lang.IllegalArgumentException:裁剪矩形不适合图像数据。 : 在 com.google.zxing.client.android.PlanarYUVLuminanceSource.(PlanarYUVLuminanceSource.java:46) : 在 com.google.zxing.client.android.camera.CameraManager.buildLuminanceSource(CameraManager.java:275) 在 com .google.zxing.client.android.DecodeHandler.decode(DecodeHandler.java:80) E/AndroidRuntime(5523): at com.google.zxing.client.android.DecodeHandler.handleMessage(DecodeHandler.java:54)
  • @Roylee ,嘿 thnks ,它正在工作,我想问一下,它可以根据传感器在风景和肖像中都工作吗,如果你可以请帮忙
  • 是的,我跟着他们去了,但它永远不会扫描我:S 虽然我找到了解决方案。不要转哈哈!我将它用于二维码,所以它可以双向工作,所以我只需从视图中删除任何文本并保留它!不过谢谢你的关心。
  • 对我有用,虽然相机图像有点超出纵横比(qrcode,nexus4)
【解决方案2】:

要支持所有方向并在旋转 Activity 时自动更改,只需修改 CameraManager.java类。

并从 CaptureActivity.java

中删除此方法 getCurrentOrientation()

在 CameraManager.java 中创建这个变量:

int resultOrientation;

将此添加到 openDriver(..) 方法中:

setCameraDisplayOrientation(context, Camera.CameraInfo.CAMERA_FACING_BACK, theCamera);//this can be set after camera.setPreviewDisplay(); in api13+.

****创建此方法**** 链接:http://developer.android.com/reference/android/hardware/Camera.html

public static void setCameraDisplayOrientation(Context context,int cameraId, android.hardware.Camera camera) {
    android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
    android.hardware.Camera.getCameraInfo(cameraId, info);
    Display display = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    int degrees = 0;
    switch (display.getRotation()) {
    case Surface.ROTATION_0: degrees = 0; break;
    case Surface.ROTATION_90: degrees = 90; break;
    case Surface.ROTATION_180: degrees = 180; break;
    case Surface.ROTATION_270: degrees = 270; break;
    }


    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        resultOrientation = (info.orientation + degrees) % 360;
        resultOrientation = (360 - resultOrientation) % 360;  // compensate the mirror
    } else {  // back-facing
        resultOrientation = (info.orientation - degrees + 360) % 360;
    }
    camera.setDisplayOrientation(resultOrientation);
}

****现在修改getFramingRectInPreview()****

if(resultOrientation == 180 || resultOrientation == 0){//to work with landScape and reverse landScape
            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;
        }else{
            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;
        }

并修改此方法public PlanarYUVLuminanceSource buildLuminanceSource(..)

if(resultOrientation == 180 || resultOrientation == 0){//TODO: This is to use camera in landScape mode
        // Go ahead and assume it's YUV rather than die.
        return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top, rect.width(), rect.height(), false);
    }else{
        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;
        return new PlanarYUVLuminanceSource(rotatedData, width, height, rect.left, rect.top, rect.width(), rect.height(), false);
    }

【讨论】:

  • 它打破了某些设备上预览的缩放比例
  • @mustafa 我相信这就是他们在自己的库版本中不支持轮换的原因。
【解决方案3】:

你可以使用我的 zxlib 的 fork https://github.com/rusfearuth/zxing-lib-without-landscape-only。我只禁用了横向模式。您可以设置横向/纵向并查看正确的相机视图。

【讨论】:

    【解决方案4】:

    CameraConfigurationManager.java 中添加camera.setDisplayOrientation(90); 对我有用。

    【讨论】:

    • 在哪里进行此更改?
    • 我想我们需要编辑zxing的源代码,我对@Samit吗?
    【解决方案5】:

    对于 zxing 3.0,工作库 https://github.com/xiaowei4895/zxing-android-portrait 纵向模式

    谢谢

    【讨论】:

      【解决方案6】:

      我认为最好的库唯一解决方案是这个......

      https://github.com/SudarAbisheck/ZXing-Orient

      您可以将它作为 maven 格式的项目的依赖项包含在 build.gradle 中...

      dependencies {
        compile ''me.sudar:zxing-orient:2.1.1@aar''
      }
      

      【讨论】:

      • 这个库不工作。 Jsut 不扫描,我得到的只是QRCodeNotFoundOnCamImage
      • @Siddharth 谢谢,是的,我已经为另一个运行良好的库编辑了答案,实际上与 ZXing BarcodeScanner 和 BarcodeScannerPlus 应用程序的方式相同。
      【解决方案7】:

      创建 AnyOrientationCaptureActivity 然后覆盖默认的 CaptureActivity 就可以了。

      public void scanCode() {
          IntentIntegrator integrator = new IntentIntegrator(this);
          integrator.setDesiredBarcodeFormats(CommonUtil.POSEIDON_CODE_TYPES);
          integrator.setPrompt("Scan");
          integrator.setCameraId(0);
          integrator.setBeepEnabled(false);
          integrator.setBarcodeImageEnabled(false);
          integrator.setOrientationLocked(false);
          //Override here
          integrator.setCaptureActivity(AnyOrientationCaptureActivity.class);
      
          integrator.initiateScan();
      }
      
      //create AnyOrientationCaptureActivity extend CaptureActivity
      public class AnyOrientationCaptureActivity extends CaptureActivity {
      }
      

      在清单中定义

      <activity
                  android:name=".views.AnyOrientationCaptureActivity"
                  android:screenOrientation="fullSensor"
                  android:stateNotNeeded="true"
                  android:theme="@style/zxing_CaptureTheme"
                  android:windowSoftInputMode="stateAlwaysHidden"></activity>
      

      【讨论】:

      • captureactivity 是正常扩展活动的替代品?
      【解决方案8】:

      【讨论】:

        【解决方案9】:

        除了@roylee 的修改之外,我还必须将以下内容应用于CameraConfigurationManager.java 以获得最佳的预览和二维码识别质量

            diff --git a/android/src/com/google/zxing/client/android/camera/CameraConfigurationManager.java b/android/src/com/google/zxing/client/android/camera/CameraConfigurationManager.java
        index cd9d0d8..4f12c8c 100644
        --- a/android/src/com/google/zxing/client/android/camera/CameraConfigurationManager.java
        +++ b/android/src/com/google/zxing/client/android/camera/CameraConfigurationManager.java
        @@ -56,21 +56,24 @@ public final class CameraConfigurationManager {
             Display display = manager.getDefaultDisplay();
             int width = display.getWidth();
             int height = display.getHeight();
        -    // We're landscape-only, and have apparently seen issues with display thinking it's portrait 
        +    // We're landscape-only, and have apparently seen issues with display thinking it's portrait
             // when waking from sleep. If it's not landscape, assume it's mistaken and reverse them:
        +    /*
             if (width < height) {
               Log.i(TAG, "Display reports portrait orientation; assuming this is incorrect");
               int temp = width;
               width = height;
               height = temp;
             }
        +    */
             screenResolution = new Point(width, height);
             Log.i(TAG, "Screen resolution: " + screenResolution);
        -    cameraResolution = findBestPreviewSizeValue(parameters, screenResolution, false);
        +    cameraResolution = findBestPreviewSizeValue(parameters, screenResolution, true);//
             Log.i(TAG, "Camera resolution: " + cameraResolution);
           }
        
           void setDesiredCameraParameters(Camera camera) {
        +    camera.setDisplayOrientation(90);
             Camera.Parameters parameters = camera.getParameters();
        
             if (parameters == null) {
        @@ -99,7 +102,7 @@ public final class CameraConfigurationManager {
           Point getScreenResolution() {
             return screenResolution;
           }
        -  
        +
           public void setFrontCamera(boolean newSetting) {
             SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
             boolean currentSetting = prefs.getBoolean(PreferencesActivity.KEY_FRONT_CAMERA, false);
        @@ -109,12 +112,12 @@ public final class CameraConfigurationManager {
               editor.commit();
             }
           }
        -  
        +
           public boolean getFrontCamera() {
             SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
             return prefs.getBoolean(PreferencesActivity.KEY_FRONT_CAMERA, false);
           }
        -  
        +
           public boolean getTorch() {
             SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
             return prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false);
        @@ -181,7 +184,14 @@ public final class CameraConfigurationManager {
               Camera.Size defaultSize = parameters.getPreviewSize();
               bestSize = new Point(defaultSize.width, defaultSize.height);
             }
        +
        +    // FIXME: test the bestSize == null case!
        +    // swap width and height in portrait case back again
        +    if (portrait) {
        +        bestSize = new Point(bestSize.y, bestSize.x);
        +    }
             return bestSize;
        +
           }
        
           private static String findSettableValue(Collection<String> supportedValues,
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-07-16
          • 1970-01-01
          • 1970-01-01
          • 2013-01-08
          • 2016-09-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多