Android中Zxing如何将方向更改为竖屏

49
我正在尝试旋转Zxing显示器,经过查阅一些问题和帖子后。按照指示进行操作后,显示器确实旋转了,但扫描仪的矩形框没有正确定位(如所附图像所示)。
这是我所做的:
  1. in CameraConfigurationManager:

    camera.setDisplayOrientation(90);
    
  2. in 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;
    
  3. in 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;
    

enter image description here


2
可能是如何在竖屏模式下使用Zxing?的重复问题。 - Sean Owen
9个回答

30

在经历了一番折磨后,我找到了问题所在,并希望它能帮助未来的某个人。

CameraConfigurationManager中的initFromCameraParameters方法假设扫描始终处于横屏模式下,因此在width < height时进行了修复。 如果您按照问题中的步骤并删除此检查,则一切正常。


1
嗨,我已经实现了步骤1和3,现在我可以以纵向查看。我找不到一个地方来实现第2步,这阻止了我在纵向模式下阅读代码。我应该把第2步的代码放在哪里?我无法在任何地方找到旋转数据的参考。谢谢。 - jim
3
@ROb:好的……朋友们……在使用字节数组rotatedData进行解码方法时,第二点已经被添加了。 - Code_Life
1
@Sam - 你需要禁用位于com.google.zxing.client.android.camera中的CameraConfigurationManager类中的检查。 搜索"We're landscape-only"并禁用此检查。 - SuperFrog
在禁用CameraConfigurationManager中的检查之前,扫描是否正常工作? - SuperFrog
有人在 Delphi Xe5 中为移动设备使用过那个解决方案吗? - Sebastian Xawery Wiśniowiecki
显示剩余6条评论

17

截至zxing库的2.2.0版本,支持方向变化已经内置。

在清单文件中添加/编辑以下内容:

<activity
    android:name="com.journeyapps.barcodescanner.CaptureActivity"
    android:screenOrientation="fullSensor"
    tools:replace="screenOrientation" />

在调用扫描仪时设置附加属性:

IntentIntegrator integrator = new IntentIntegrator(this);

//allows portrait/landscape mode
integrator.setOrientationLocked(false);//"additional property"
integrator.initiateScan();

参考链接: https://github.com/journeyapps/zxing-android-embedded#changing-the-orientation


this is what I need. Thanks - Ufuk Ugur
这对我也起作用了。值得一提的是,即使从不同的Activity/Fragment调用IntentIntegrator,也应该将其添加到清单中。 - moyheen
也适用于我。 - WHOATEMYNOODLES
这个方法对我有效。谢谢兄弟。 - Arjun G
@ArnoldBrown 我知道这是一个旧的线程,你可能已经找到了解决方案。但为了后人着想,请将 android:screenOrientation="fullSensor" 设置为 android:screenOrientation="sensorPortrait",尽管它可能会警告使用 fullSensor - Patrick Davis
显示剩余2条评论

14

谢谢你的答复!它确实帮了我很大的忙。我注意到至少在zxing 2.1版本中,您需要将“rotatedData”传递给buildLuminanceSource而不仅仅是“data”,代码行应像这样结束:

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

希望这能帮助到其他人!


好的,在答案上方我也添加了你的,谢谢,它有效! - Roy Lee
我感觉很蠢,没有改变这个。谢谢,这是对问题和接受的答案提供的信息非常好的补充! - chuky

8

我在ProjectLibrary(xzing项目)中做了一个小改变,成功将方向从横屏改为竖屏

CameraConfigurationManager类的setDesiredCameraParameters方法中添加代码

camera.setDisplayOrientation(90);

在原始项目的AndroidManifest.xml文件中,我设置了screenOrientation = portrait,并且在我的ICS 4.0.3上运行良好。

   <activity
        android:name="com.google.zxing.client.android.CaptureActivity"
        android:configChanges="orientation|keyboardHidden"
        android:exported="false"
        android:screenOrientation="portrait"
        android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
        android:windowSoftInputMode="stateAlwaysHidden" >
        <intent-filter>
            <action android:name="com.phonegap.plugins.barcodescanner.SCAN" />

            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity> 

5
  1. In CameraConfigurationManager:

    camera.setDisplayOrientation(90);
    
  2. In 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;
    
  3. In 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;
    
  4. In CameraConfigurationManager:

    if    (width > height) {
      Log.i(TAG, "Display reports portrait orientation; assuming this is incorrect");
      int temp = width;
      width = height;
      height = temp;
    }
    
  5. Change android:screenOrientation="portrait" for CaptureActivity in manifest.


这对我有用。如果@Dayanand能指示如何进行这些更改的方法,那就太好了。我需要做的唯一额外更改是在CaptureActivity#onResume中注释掉明确的setRequestedOrientation - MikeNereson
这是在编辑zxing库的源代码吗? - gumuruh

4
我是一名条形码扫描应用程序的开发者。是的,要让它在竖屏模式下进行扫描需要更多的工作。您需要“旋转”图像数据,并考虑设备的方向,其默认方向以及其传感器的方向。 Barcode Scanner+ 可以在竖屏模式下进行扫描,您可以通过Intent与其集成,方式与您与Barcode Scanner集成完全相同。(不过这是一个付费应用程序。)

它可以旋转和扫描,唯一的问题是矩形的位置。 - SuperFrog
我认为你在上面的代码中颠倒了x和y。至少显示是这样的。x应该与x配对。 - Sean Owen
翻转是有意的,因为我在这里看到了一个例子:http://code.google.com/p/zxing/issues/detail?id=178#c46 - SuperFrog
肯定有些东西被翻转了,正如您从图像中所看到的那样。它的行为就像处于横向模式一样。您确定 cameraResolutionscreenResolution 是您想要的吗? - Sean Owen

1
我曾尝试过其他答案中提到的各种补丁,但条形码识别仍然不可靠。
我强烈推荐在纵向模式下使用以下存储库。它很快速和稳定。我在我的混合应用程序中使用了它。

https://github.com/Dbuggerx/BarcodeScanner


1

尝试这样做:添加 android:screenOrientation="sensorPortrait"

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

0
在您的库中,转到清单文件,在活动标签下更改以下行:
android:screenOrientation="portrait"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接