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

编码

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

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

精简过后该项目起名为XBarcodeGenerator

可以实现的功能包括:

  • 分享联系人

  • 分享剪切板

  • 编码输入文本

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

解码

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

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

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

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

  • 调整横屏为竖屏展示

  • 美化viewfinderview(可选)

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

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

修改AndroidManifest.xml中:

  1. android:screenOrientation=“landscape"

  1. android:screenOrientation="portrait"

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

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

  1. camera.setDisplayOrientation(90);

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

参考:Camera.setDisplayOrientation(int)

3. 调整扫描窗口尺寸

修改CameraManager.getFramingRectInPreview()中的

  1. public synchronized Rect getFramingRectInPreview() {
  2. ...
  3. rect.left = rect.left * cameraResolution./ screenResolution.x;
  4. rect.right = rect.right * cameraResolution./ screenResolution.x;
  5. rect.top = rect.top * cameraResolution./ screenResolution.y;
  6. rect.bottom = rect.bottom * cameraResolution./ screenResolution.y;
  7. framingRectInPreview = rect;
  8. ...
  9. }

修改为:

  1. public synchronized Rect getFramingRectInPreview() {
  2. ...
  3. rect.left = rect.left * cameraResolution./ screenResolution.x;
  4. rect.right = rect.right * cameraResolution./ screenResolution.x;
  5. rect.top = rect.top * cameraResolution./ screenResolution.y;
  6. rect.bottom = rect.bottom * cameraResolution./ screenResolution.y;
  7. framingRectInPreview = rect;
  8. ...
  9. }

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

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

  1.     public synchronized Rect getFramingRect() {
  2.         if (framingRect == null) {
  3.             if (camera == null) {
  4.                 return null;
  5.             }
  6.             Point screenResolution = configManager.getScreenResolution();
  7.             if (screenResolution == null) {
  8.                 // Called early, before init even finished
  9.                 return null;
  10.             }
  11.  
  12.             int width = findDesiredDimensionInRange(screenResolution.x, MIN_FRAME_WIDTH,
  13.                     MAX_FRAME_WIDTH);
  14.             // 将扫描框设置成一个正方形
  15.             int height = width;
  16.  
  17.             int leftOffset = (screenResolution.- width) / 2;
  18.             int topOffset = (screenResolution.- height) / 2;
  19.             framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
  20.             
  21.             Log.d(TAG, "Calculated framing rect: " + framingRect);
  22.         }
  23.         
  24.         return framingRect;
  25.     }

让height=width即可

5. 反转扫描到的图形

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

  1. private void decode(byte[] data, int width, int height) {
  2. long start = System.currentTimeMillis();
  3. Result rawResult = null;
  4.  
  5. // 新增反转数据代码开始
  6. byte[] rotatedData = new byte[data.length];
  7. for (int y = 0; y < height; y++) {
  8. for (int x = 0; x < width; x++)
  9. rotatedData[* height + height - y - 1] = data[+ y * width];
  10. }
  11. int tmp = width; 
  12. width = height;
  13. height = tmp;
  14. // 新增结束
  15.  
  16. PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(rotatedData,
  17. width, height);
  18. if (source != null) {
  19. BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
  20. try {
  21. // 预览界面最终取到的是个bitmap,然后对其进行解码
  22. rawResult = multiFormatReader.decodeWithState(bitmap);
  23. } catch (ReaderException re) {
  24. // continue
  25. } finally {
  26. multiFormatReader.reset();
  27. }
  28. }
  29. ...

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

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

[转]【基于zxing的编解码实战】精简Barcode Scanner篇的更多相关文章

  1. 视频编解码学习之路(H264)

    学习视频编解码技术很难吗?视频编解码技术的未来是什么? 明了的说,无论是软件还是硬件设计,视频编解码技术有很多难点,都需要很长一段时间积累才行. 从一开始接触MPEG-2到最新的H.264标准,可算走 ...

  2. (中级篇 NettyNIO编解码开发)第八章-Google Protobuf 编解码-2

    8.1.2    Protobuf编解码开发 Protobuf的类库使用比较简单,下面我们就通过对SubscrjbeReqProto进行编解码来介绍Protobuf的使用. 8-1    Protob ...

  3. 音视频编解码问题:javaCV如何快速进行音频预处理和解复用编解码(基于javaCV-FFMPEG)

    前言: 前面我用了很多章实现了javaCV的基本操作,包括:音视频捕捉(摄像头视频捕捉和话筒音频捕捉),推流(本地音视频或者摄像头话筒混合推流到服务器),转流(rtsp->rtmp),收流(录制 ...

  4. 【并行计算与CUDA开发】基于NVIDIA显卡的硬编解码的一点心得 (完结)

    原文:基于NVIDIA显卡的硬编解码的一点心得 (完结) 1.硬解码软编码方法:大体流程,先用ffmpeg来读取视频文件的包,接着开启两个线程,一个用于硬解码,一个用于软编码,然后将读取的包传给解码器 ...

  5. 基于3U PXIe的ZU7EV图像编解码设计方案

    1.板卡简介 基于3U PXIe的ZU7EV图像编码卡用于加固设备的图像接入,编解码采集存储.用于机载.舰载.车载等工作场景,支持工业级温度工作.(此方案是由北京太速设计的,已应用到实际领域) 2.主 ...

  6. 基于ffmpeg的简单音视频编解码的例子

    近日需要做一个视频转码服务器,对我这样一个在该领域的新手来说却是够我折腾一番,在别人的建议下开始研究开源ffmpeg项目,下面是在代码中看到的一 段例子代码,对我的学习非常有帮助.该例子代码包含音频的 ...

  7. Android实战技巧之三十七:图片的Base64编解码

    通经常使用Base64这样的编解码方式将二进制数据转换成可见的字符串格式,就是我们常说的大串.10块钱一串的那种,^_^. Android的android.util包下直接提供了一个功能十分完备的Ba ...

  8. [转]FFMPEG视音频编解码零基础学习方法

    在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“ ...

  9. [总结]FFMPEG视音频编解码零基础学习方法--转

    ffmpeg编解码学习   目录(?)[-] ffmpeg程序的使用ffmpegexeffplayexeffprobeexe 1 ffmpegexe 2 ffplayexe 3 ffprobeexe ...

随机推荐

  1. Mac OS X 系统下快速显示隐藏文件的方法(使用Automator创建workflow)

    有的时候需要显系统中的隐藏文件,在 Mac 中不像windows系统那么方便(勾选选项就能够操作),需要在 Terminal 中执行: localhost:~ mx$ defaults write c ...

  2. chrome调试状态下动态加载的js

    在js文件中加入 //@ sourceURL=文件名.js

  3. form WebBrowser自动点击弹出提示框alert、弹出对话框confirm、屏蔽弹出框、屏蔽弹出脚本错误的解决办法

    针对WebBrowser控件中自动点击弹出框及禁用脚本提示问题得到如下几种实际情况的解决办法,绝对管用. 1.屏蔽弹出错误脚本 将WebBrowser控件ScriptErrorsSuppressed设 ...

  4. 通过命令修改wampserver的mysql密码

    WAMP安装好后,mysql教程密码是为空的,那么要如何修改呢?其实很简单,通过几条指令就行了,下面我就一步步来操作. 首先,通过WAMP打开mysql控制台. 提示输入密码,因为现在是空,所以直接按 ...

  5. Flask 富文本编辑器

    XHEditor http://segmentfault.com/blog/digwtx/1190000002439076 CKeditor http://segmentfault.com/blog/ ...

  6. “layout_”下划线开头的属性

    观看幕课网的视频的收获 “layout_”下划线开头的属性都是交给父容器去处理的属性,如: android:layout_width="match_parent" android: ...

  7. BZOJ 3240 矩阵游戏

    Description 婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的\(n\)行\(m\)列的矩阵(你不用担心她如何存储).她生成的这个矩阵满足一个神奇的性质:若用\(F[i][j]\)来 ...

  8. activiti入门3排他网关,并行网管,包含网关,事件网关(转)

    网关用来控制流程的流向 网关可以消费也可以生成token. 网关显示成菱形图形,内部有有一个小图标. 图标表示网关的类型. 基本分支 首先 利用 流程变量  写个带有分支的一个基本流程 流程图: 部署 ...

  9. 深入浅出 Java Concurrency (3): 原子操作 part 2

    转:http://www.blogjava.net/xylz/archive/2010/07/02/325079.html 在这一部分开始讨论数组原子操作和一些其他的原子操作. AtomicInteg ...

  10. Maven实战一

    转载:http://www.iteye.com/topic/1123221 1. 用Maven 命令创建一个简单的Maven项目 在cmd中运行如下命令: Cmd代码 mvn archetype:ge ...