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)
在这里插入图片描述在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值