Zxing3.3.3 竖屏修改

参考文章 https://www.jianshu.com/p/a4ba10da4231

一、ZXing 项目

1.https://github.com/zxing/zxing

在这里插入图片描述

2.新建module

使用Android Studio 新建一个工程 包名设置为com.google.zxing.client.android(与zxing android工程包名一样,省去一些手工导包修改过程操作)

2.1 gradle 引入zxing核心架包core 和 android-core
dependencies {
    implementation 'com.google.zxing:core:3.3.3'
    implementation 'com.google.zxing:android-core:3.3.0'
}
2.2 简单横屏转竖屏修改

参考https://github.com/zxing/zxing/issues/576
参考https://github.com/zxing/zxing/issues/111
@GuoJinyu用户的修改: https://github.com/zxing/zxing/issues/111#issuecomment-263175368


@srowen
I think the most important point to support for Android portrait mode is rotating the YUV preview frame data array, because the preview frame you get is only relative to the camera’s orientation (always landscape at nearly all of Android phones) which has no relation to the screen’s orientation.
So this is my steps to support portrait mode in version 4.7.7:

1. Removing "android:screenOrientation="sensorLandscape" in AndroidManifest.xml
2. Changing lines from 172 to 176 in CaptureActivity.java to support both landscape and portrait

if (prefs.getBoolean(PreferencesActivity.KEY_DISABLE_AUTO_ORIENTATION, true)) {
    setRequestedOrientation(getCurrentOrientation());
} else {
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}

3. Changing lines from 327 to 329 in CameraConfigurationUtils.java to get proper aspectRatio in accordence with screen orientation

boolean isScreenPortrait = screenResolution.x < screenResolution.y;
int maybeFlippedWidth = isScreenPortrait ? realHeight : realWidth;
int maybeFlippedHeight = isScreenPortrait ? realWidth : realHeight;

4. Changing lines from 266 to 269 in CameraManager.java to get precise preview rectangle for camera.

if(screenResolution.x < screenResolution.y){
    // portrait
    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;
 } else {
    // 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;
}

5. Changing lines from 47 to 48 in PreviewCallback.java to send proper width and height of preview frame

Point screenResolution = configManager.getScreenResolution();
Message message;
if (screenResolution.x < screenResolution.y){
    // portrait      
    message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.y,
          cameraResolution.x, data);
} else {
    // landscape
    message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,
    	   cameraResolution.y, data);
}

6. Adding lines between 76 and 77 in DecodeHandler.java to rotate data when portrait

long start = System.currentTimeMillis();
if (width < height) {
    // portrait
    byte[] rotatedData = new byte[data.length];
    for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++)
            rotatedData[y * width + width - x - 1] = data[y + x * height];
    }
    data = rotatedData;
}
Result rawResult = null;

7. To support portrait mode perfectly, you should also do this follow my comment in this issue

Above-mentioned code modify has been tested on both 1D and 2D code and works good in my two Android phones with back camera.

BTW, I have published an Android scanner library by simplifying this Android project SimpleZXing


2.3 zxing3.3.3 版本修改

1. AndroidManifest.xmlCaptureActivity设置竖屏android:screenOrientation="portrait"

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

2.CameraManager.java 中方法getFramingRectInPreview()修改

    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;
            }

            boolean isScreenPortrait = screenResolution.x < screenResolution.y;
            boolean isCameraSizePortrait = cameraResolution.x < cameraResolution.y;
            if (isScreenPortrait == isCameraSizePortrait) {
                /*默认 横屏*/
                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;
            }
            framingRectInPreview = rect;
        }
        return framingRectInPreview;
    }

3.DecodeHandler.javadecode(byte[] data, int width, int height) 修改

 private void decode(byte[] data, int width, int height) {
        long start = System.nanoTime();
        Result rawResult = null;
        if (isScreenPortrait()) {
            //竖屏
            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;
            data = rotatedData;
        }
        PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height);
        if (source != null) {
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
            try {
                rawResult = multiFormatReader.decodeWithState(bitmap);
            } catch (ReaderException re) {
                // continue
            } finally {
                multiFormatReader.reset();
            }
        }
        ...省略


  private boolean isScreenPortrait() {
        WindowManager manager = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
        Display display = manager.getDefaultDisplay();
        Point screenResolution = new Point();
        display.getSize(screenResolution);
        return screenResolution.x < screenResolution.y;
    }

4. 个别参数修改,如,扫码区自动对焦、扫描区域上移
CameraManager.java 里面 扫描区域偏上getFramingRect()、扫码区自动对焦openDriver(SurfaceHolder holder)
在这里插入图片描述在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Delphi是一种编程语言,而ZXing(Zebra Crossing)是一个开源的条码和二维码处理库。要实现在Delphi中调用ZXing 3.3.3来实现仿微信的扫描二维码和条形码功能,首先需要集成ZXing库到Delphi项目中。 第一步是下载ZXing 3.3.3的源代码。可以在ZXing的GitHub页面上找到最新的版本。解压下载的压缩文件并将其中的源代码文件复制到Delphi项目的目录中。 接下来,在Delphi中创建一个新的Form(窗体)来放置扫描二维码的UI界面。可以使用Delphi自带的UI设计工具来创建界面,添加一个按钮,一个文本框以及用于图像显示的容器。 然后,在Delphi中添加ZXing的库文件。在Delphi的菜单栏中选择“项目”,然后点击“选项”菜单。在“环境选项”对话框中,选择“Delphi”下的“编译器”选项,点击“搜索路径”并点击“添加”,浏览并选择ZXing库的源代码所在的文件夹。 接下来需要在Delphi代码中添加ZXing的功能代码。可以找到相应的代码示例或者教程来了解如何在Delphi中调用ZXing的扫描功能。通常需要在按钮的点击事件中添加ZXing的扫描方法,并将扫描结果显示在文本框中。 最后,运行Delphi项目并测试扫码功能。点击按钮,打开相机并进行扫描。扫描结果将会显示在文本框中。 总的来说,要实现在Delphi中调用ZXing 3.3.3来实现仿微信的扫描二维码和条形码功能,主要步骤是集成ZXing库到Delphi项目中,创建相应的UI界面,在代码中添加ZXing的功能方法,并测试运行实现扫码功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值