zoukankan      html  css  js  c++  java
  • [转]【基于zxing的编解码实战】精简Barcode Scanner篇

    通过《【搞定条形码】zxing项目源码解读(2.3.0版本,Android部分)》的分析,现在可以实现最终目标了:精简Barcode Scanner并将其中的编码和解码分离为两个独立的部分,方便日后快速集成到自己的项目中去。

    编码

    在上一篇分析中,对于编码部分已经有所透露,核心部分只有两个package。现在将分享的部分再去掉分享app、分享书签的功能,保留分享剪切板和分享联系人以及编码文本的功能:

    image

    编码部分的逻辑清晰,代码组织整齐,在前面了解zxing整体结构的基础上一直做减法即可。

    精简过后该项目起名为XBarcodeGenerator

    可以实现的功能包括:

    • 分享联系人

    • 分享剪切板

    • 编码输入文本

    主界面布局稍稍修改了下,新增了一个按钮。代码托管至:Zxing-Simplification

    解码

    在Barcode Scanner的基础上,做出以下调整:

    • 去掉编码部分。去掉整个com.google.zxing.client.android.encode包及相应布局

    • 去掉分享部分。去掉com.google.zxing.client.android.share包及相应布局

    • 精简设置。去掉“自定义搜索网址”,修改前灯的描述,默认使用自动对焦,去掉搜索国家,没有持续关注

    • 调整横屏为竖屏展示

    • 美化viewfinderview(可选)

    调整横屏为竖屏进行扫描共分为5步:

    1. 调整CaptureActivity的方向为竖屏显示

    修改AndroidManifest.xml中:

    android:screenOrientation=“landscape"

    android:screenOrientation="portrait"

    2. 调整相机预览界面方向

    在CameraConfigurationManager.setDesiredCameraParameters的最后增加一行代码:

    camera.setDisplayOrientation(90);

    调整相机preview的时钟方向与手机竖屏的自然方向一致。该方法必须在startPreview之前被调用,在预览界面展示出来后设置是无效的。

    参考:Camera.setDisplayOrientation(int)

    3. 调整扫描窗口尺寸

    修改CameraManager.getFramingRectInPreview()中的

    public synchronized Rect getFramingRectInPreview() {
    ...
    		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;
    		framingRectInPreview = rect;
    ...
    }

    修改为:

    public synchronized Rect getFramingRectInPreview() {
    ...
    		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;
    ...
    }

    由于修改了屏幕的初始方向,手机分辨率由原来的width*height变为height*width形式,但是相机的分辨率则是固定的,因此这里需做些调整以计算出正确的缩放比率。

    4. 将扫描框设置为正方形

        public synchronized Rect getFramingRect() {
            if (framingRect == null) {
                if (camera == null) {
                    return null;
                }
                Point screenResolution = configManager.getScreenResolution();
                if (screenResolution == null) {
                    // Called early, before init even finished
                    return null;
                }
    
                int width = findDesiredDimensionInRange(screenResolution.x, MIN_FRAME_WIDTH,
                        MAX_FRAME_WIDTH);
                // 将扫描框设置成一个正方形
                int height = width;
    
                int leftOffset = (screenResolution.x - width) / 2;
                int topOffset = (screenResolution.y - height) / 2;
                framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
                
                Log.d(TAG, "Calculated framing rect: " + framingRect);
            }
            
            return framingRect;
        }

    让height=width即可

    5. 反转扫描到的图形

    修改DecodeHandler.decode方法,增加以下代码

    private void decode(byte[] data, int width, int height) {
    	long start = System.currentTimeMillis();
    	Result rawResult = null;
    	
    	
    	// 新增反转数据代码开始
    	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);
    	if (source != null) {
    		BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
    		try {
    			// 预览界面最终取到的是个bitmap,然后对其进行解码
    			rawResult = multiFormatReader.decodeWithState(bitmap);
    		} catch (ReaderException re) {
    			// continue
    		} finally {
    			multiFormatReader.reset();
    		}
    	}
    ...

    如果要仿照微信做一个扫描窗口,可参考《基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果》

    精简过后该项目起名为XBarcodeScanner,代码托管至:Zxing-Simplification

  • 相关阅读:
    艾伦 Visual Studio 批量自动化代码操作工具-VS插件发布
    Visual Studio 打开解决方案后 弹出框显示 "正在打开文件..." 迟迟没反应 的解决方法
    小米抢购神器-开放源码
    python语法
    python运算符
    python字符串
    python多线程,多进程编程。
    subprocess模块
    jenkins
    python中的lxml模块
  • 原文地址:https://www.cnblogs.com/exmyth/p/4876136.html
Copyright © 2011-2022 走看看