如何在肖像模式下使用Zxing?

目前zxing库仅支持横向模式。对于我的应用程序,我需要使用纵向模式

Solutions Collecting From Web of "如何在肖像模式下使用Zxing?"

只要看看在纵向模式下使用Zxing的问题。

setDisplayOrientation(int)不影响在PreviewCallback.onPreviewFrame传递的字节数组的顺序。 (有关更多信息,请参阅JavaDoc)

这意味着你需要旋转从previewCallback返回的数据,但这是yuv的数据,你需要转换为rgb数据,然后旋转它们。 可以在纵向模式下扫描条形码,但需要更长时间,因为需要更多的时间来处理从yuv到rgb的数据并旋转rgb数据。 所以这里的问题是如何从portraitcallback中获取yuv数据以用于纵向模式? 当我们为相机参数设置setPreviewSize时,如果不支持previewsize,它会得到exception。 这是这个问题的问题。 如果相机驱动程序不支持纵向模式的previewSize(高度>宽度),则无法在纵向模式下获取yuv数据。 而其余的依赖于你,你可以扫描条形码模式,但它需要时间更长,或者你必须改变屏幕的方向为风景,以获得更快的结果。

这是肖像模式扫描的解决scheme

首先在你的应用级别的gradle文件中声明这两行

 compile 'com.journeyapps:zxing-android-embedded:3.0.1@aar' compile 'com.google.zxing:core:3.2.0' 

在你的xml文件中定义一个button,在MainActivity java文件中的Onclickbutton的监听器中写下面的代码

 IntentIntegrator integrator = new IntentIntegrator(this); integrator.setPrompt("Scan a barcode"); integrator.setCameraId(0); // Use a specific camera of the device integrator.setOrientationLocked(true); integrator.setBeepEnabled(true); integrator.setCaptureActivity(CaptureActivityPortrait.class); integrator.initiateScan(); 

在onCreate()方法之后,在MainActivity java文件中写下面的代码

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data); if(result != null) { if(result.getContents() == null) { Log.d("MainActivity", "Cancelled scan"); Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show(); } else { Log.d("MainActivity", "Scanned"); st_scanned_result = result.getContents(); Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show(); } } } 

然后创build一个名为CaptureActivityPortrait的类来扩展CaptureActivity。 这个类看起来像下面

  package soAndSo(Your PackageName); import com.journeyapps.barcodescanner.CaptureActivity; public class CaptureActivityPortrait extends CaptureActivity { } 

最重要的是声明你的CaptureActivityPortrait清单文件,如下所示

 <activity android:name=".CaptureActivityPortrait" android:screenOrientation="portrait" android:stateNotNeeded="true" android:theme="@style/zxing_CaptureTheme" android:windowSoftInputMode="stateAlwaysHidden"></activity> 
  1. 为了使画面在纵向上工作,为活动设置纵向(例如在清单中),然后configuration摄像机:在CameraConfigurationManager.setDesiredCameraParameters(Camera camera)中使用camera.setDisplayOrientation(90)。 但请注意:

    • setDisplayOrientation(int)需要Android 2.2
    • setDisplayOrientation(int)不影响在PreviewCallback.onPreviewFrame中传递的字节数组的顺序。 (有关更多信息,请参阅JavaDoc)
  2. 由于预览帧始终处于“横向”状态,因此我们需要旋转它们。 我使用了评论#11提供的顺时针旋转。 旋转后不要忘记交换宽度和高度参数。 DecodeHandler.java,旋转数据在buildLuminanceSource之前解码(byte [] data,int width,int height)

     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; 
  3. 我还修改了CameraManager.java,getFramingRectInPreview(),正如#c11所推荐的那样:

     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. 我没有修改getCameraResolution()。 这是#c11的第二个区别。

结果,我得到了UPC和其他一维码扫描工作的肖像。

PS也可以调整FramingRect的大小(这是在扫描期间在屏幕上可见的矩形),并且FramingRectInPreview将被自动调整。

使用这个android库https://github.com/SudarAbisheck/ZXing-Orient

它支持纵向和横向。