安卓系统下生成QR码(四)——强制设置掩膜
来源:互联网 发布:淘宝保证金能退吗 编辑:程序博客网 时间:2024/05/16 09:30
为了增加QR码识别读取时的可靠性,应该防止编码时黑色块和白色块过于密集地集中在一片区域上,那就需要编码时均匀地在编码区上合理地摆放每一个黑白信息位,而且还要避免出现类似其它功能图形的黑白块,特别是行或者列的黑白块以1011101这种形式出现,那就与位置探测图形的行和列一致,这肯定会造成在解码识别时对位流的误判。
先看看掩膜效果的过程以及评价方法:
掩膜过程:
评价标准:
经过上表的规则计算处理后,掩模效果会得到一个具体的数值。这个数值代表着掩模结果的评价,它越大说明在进行的这次掩模过程中符合表中所述的特征数量多,总体表现为掩模的质量差。为了使QR码的阅读识别具有一定的可靠性,最后应采用得分最小的一个掩模条件用于QR码的最终掩模。虽然掩模操作仅对数据码块与纠错码块的编码区域有效,但是掩模的评价是采取了整个QR码的有效区域来计算的....(省略十万字)
欣赏一下Zxing原生的掩膜评价函数:
private static int chooseMaskPattern(BitArray bits,ErrorCorrectionLevel errLevel, Version version,ByteMatrix matrix) throws WriterException { int minPenalty = Integer.MAX_VALUE; // 掩模越低越好Integer.MAX_VALUE=2的31次方-1 int bestMaskPattern = -1; int mask_penalty = 0; // 尝试8种掩码模式来选择最好的掩模 ==8 for (int maskPattern = 0; maskPattern < 8; maskPattern++) { MatrixUtil.buildMatrix(bits, errLevel, version, maskPattern, matrix); mask_penalty = calculateMaskPenalty(matrix); if (mask_penalty < minPenalty) { minPenalty = mask_penalty; bestMaskPattern = maskPattern; } } Log.e("——————————————————", "掩模质量mask_penalty:"+mask_penalty); return bestMaskPattern; }
static void buildMatrix(BitArray dataBits, ErrorCorrectionLevel ecLevel, Version version, int maskPattern, ByteMatrix matrix) throws WriterException { clearMatrix(matrix); embedBasicPatterns(version, matrix); // 类型信息以任何版本出现 embedTypeInfo(ecLevel, maskPattern, matrix); // 版本> = 7 maybeEmbedVersionInfo(version, matrix); // 数据应该被嵌入到最后 embedDataBits(dataBits, maskPattern, matrix); }
// 计算掩模,4种评分规则相加,越低说明掩模质量越好 private static int calculateMaskPenalty(ByteMatrix matrix) { return MaskUtil.applyMaskPenaltyRule1(matrix) + MaskUtil.applyMaskPenaltyRule2(matrix) + MaskUtil.applyMaskPenaltyRule3(matrix) + MaskUtil.applyMaskPenaltyRule4(matrix); }
虽然说Zxing在生成QR码时是自动选择8种掩膜效果最好的一种,作为控制欲强的星座,喜欢折腾的我是有点不爽,完成了掩膜的强制设置。
效果就是随心所需设置你想要的掩膜:
首先,为这8种掩膜的选择添加到一个Spinner:
布局代码:
<Spinner android:id="@+id/user_set_mask_spinner" android:layout_width="60dp" android:layout_height="30dp" android:background="@drawable/selector_bt_bg" android:layout_alignTop="@+id/TextView03" android:layout_toRightOf="@+id/TextView03" android:layout_marginTop="-5dp" android:layout_marginLeft="4dp" android:paddingLeft="5dp" android:entries="@array/user_set_mask" />
其中,user_set_mask是Spinner的array数据:
<string-array name="user_set_mask"> <item>自 动</item> <item>模板0</item> <item>模板1</item> <item>模板2</item> <item>模板3</item> <item>模板4</item> <item>模板5</item> <item>模板6</item> <item>模板7</item> </string-array>点击Spinner后:
Spinner控件的监听处理:
user_set_mask_spinner.setOnItemSelectedListener(new OnItemSelectedListener() {@Overridepublic void onItemSelected(AdapterView<?> parent,View view, int pos, long id) {user_set_mask = pos - 1;}@Overridepublic void onNothingSelected(AdapterView<?> parent) {// Another interface callback}});
user_set_mask是具体的掩膜版本,注意:其数值要等于点击Spinner控件的pos位置减1。
接下来就像《安卓系统下生成QR码(二)——自定义二维码的纠错等级》一样的过程。
先在EncodeHintType添加一个枚举(如果没有):
public enum EncodeHintType {// 矫错等级ERROR_CORRECTION, //掩模MASK}
处理user_set_mask,形成能让Zxing接收的哈希表形式,并向CodeWriter的encode方法传递哈希表:
Hashtable hints = new Hashtable();hints.put(EncodeHintType.MASK, user_set_mask);QRCodeWriter CodeWriter = new QRCodeWriter();matrix = CodeWriter.encode(content, CODE_WIDTH, CODE_WIDTH, hints);encode方法接收哈希表种的user_set_mask的信息并处理:
public BitMatrix encode(String contents, int width, int height, Map<EncodeHintType,?> hints) throws WriterException { int user_set_mask=-1;try { user_set_mask=(Integer) hints.get(EncodeHintType.MASK); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } code = Encoder.encode(contents, errorCorrectionLevel,user_set_mask,hints); return renderResult(code, width, height, quietZone); }
最后,在Encoder类里的encode方法对应的地方做如下接收处理:
public static QRCode encode(String content,ErrorCorrectionLevel errLevel,int user_set_mask, Map<EncodeHintType,?> hints) throws WriterException {if(user_set_mask<=7&&user_set_mask>=0)//强制设置掩模 maskPattern=user_set_mask;}到此为止,QR码的强制设置掩膜已经完成。
- 安卓系统下生成QR码(四)——强制设置掩膜
- 安卓系统下生成QR码(一)——自定义生成图片大小
- 安卓系统下生成QR码(二)——自定义二维码的纠错等级
- 安卓系统下生成QR码(三)——自定义二维码的颜色
- 基于Excel的QR二维码生成工具——原理及算法详解(之四)
- QR码生成原理(一)
- QR码生成原理(一)
- QR码生成原理(一)
- QR码生成原理(一)
- QR码生成原理(一)
- QR码生成原理(一)
- QR码生成原理
- 强制解除安卓系统密码
- 安卓系统下 用C语言设置系统时间
- 安卓系统设置
- QR码生成原理-QR Code(ISO 18004)编码方式
- Javascript生成二维码(QR)
- Javascript生成二维码(QR)
- 转载:JNI中的jclass和jobject
- mongoDB日期解决
- 169. Majority Element (9月8日)
- Java精华知识点汇总(Most Common Problems in Interview for Java Engineer)
- mysql,5.7:ERROR 1698 (28000): Access denied for user 'root'@'localhost'
- 安卓系统下生成QR码(四)——强制设置掩膜
- HandlerThread实现数字时钟
- 最大报销额
- 数据库引擎介绍
- Java类的初始化顺序
- 网络编程之UDP协议和TCP协议
- android 沉浸式2种
- Java基础之集合框架--Collection根接口(集合框架的共性功能)
- Ubuntu常用命令大全