LittlevGL图形框架扩展 - 二维码的支持

简介: 二维码这个小图案现在已经是我们生活中不可或缺的一部分了,饭店点餐,添加好友,付钱转账,登录账号等等都只要扫一扫,方便又快捷。二维码的前身其实就是一维码,也就是条形码。
转自HaaS技术社区

1、二维码发展史

二维码这个小图案现在已经是我们生活中不可或缺的一部分了,饭店点餐,添加好友,付钱转账,登录账号等等都只要扫一扫,方便又快捷。二维码的前身其实就是一维码,也就是条形码。

条形码可以在水平方向,通过黑白相间的条纹来存储一些数字或者字母的信息,制作十分简单,但是有着存储容量不足、易复制、无法表示汉字等缺点,为此人们继续考虑同时从水平方向与垂直方向去存储信息,进而在上世纪90年代产生了二维码,并开始广泛运用于生活。二维码用某种特定的几何图形按一定规律在二维空间上分布的黑白相间的图形中记录数据符号信息。

2、跟条形码区别

2.1、承载的信息量远大于条形码

组成条形码的信息部分只能是字母和数字,而且尺寸较大,导致空间利用率较低。这就决定了其信息量不大的局限性。它的数据容量较小一般只可容纳30个字符左右。二维码就不一样了,它的信息承载量很大,最大数据含量可达1850个字符。信息内容可包含字母,数字,汉字,字符,片假名等。信息含量非常丰富。所以二维码也逐渐被市场所接受,汉字的加入更开拓了中国这个大市场。

2.2、信息表达方式不一样

根据其特性及结构可以看到,条形码只能在水平方向单向的表达商品信息,而在垂直方向则不表达任何信息,它有一定高度通常是为了便于条码设备的对准读取。而二维码在水平和垂直方向都可表达信息,也就是说它在二维空间内存储信息。

2.3、外在结构不一样

image.png

image.png

根据上图可知,它们的结构完全不同。条形码是用条空在水平方向上表达信息的条码。外形更接近矩形。二维码可以说是正方形,在其内部有三个“回”字型的定位点,可以帮助扫码设备对焦,便于读取数据。也正是它们结构的差异,使条形码没有较强的纠错功能,如果有破损就不能被读取。对于二维码来说,即使有破损,也可以正常读取。其破损纠错率可达7%~30%。

2.4、码制不一样

在目前的码制中,条形码和二维码各有自己的码制和组成成员。常用的条形码的码制包括:EAN码、39码、交叉25码、UPC码、128码、93码,ISBN码,及Codabar(库德巴码)等;常用的二维码码制有:PDF417二维条码, Datamatrix二维条码, , QR Code, Code 49, Code 16K ,Code one等。

2.5、优缺点表现

一维码的优点是在一个方向表达信息,其一定的高度通常是为了便于扫描器的对准、一维码可以提高信息录入的速度,减少差错率。缺点是数据的容量比较小,需要计算机数据库,一维码被破坏后便不能读取,容错率低。

二维码的优点是信息容量大,编码范围广,成本较低,容易制作,不需要数据库本身就能储存大量数据,二维码的容错机制保证了图片部分被破坏后还能正确识别,容错率可以高达30%。缺点是容易被不法分子植入病毒盗取用户信息或各种吸费软件。

3、LittlevGL对条形码及二维码的支持

在POS机等支付行业,二维码比条形码更为常用,因此图形框架对二维码的支持也是必须的,在二维码中QR Code对字母,数字,汉字等支持的容量很大,因此GUI图形框架的扩展主要考虑对QR Code的支持。

目前LittlevGL并不支持QR code码,因此添加如下代码,其中int16 width代表生成的二维码的宽跟高,char *cid则是二维码对应的字符串:

lv_obj_t *qrcode_gen(lv_obj_t * par, const char *cid, int px, int py, int width)
 
{
 
    int src_buf_size, dst_buf_size, qr_w, idx;
 
    int qr_pixel_width = 1;
 
    int version = QR_STD_VERSION;
 
    unsigned char *qr_data;
 
    QRcode *qrcode;
 
 
 
    if(par == NULL) par = lv_scr_act();
 
    qrcode = QRcode_encodeString(cid, version, QR_ECLEVEL_Q, QR_MODE_8, 1);
 
    if ((!qrcode) || (qrcode->width <= 0)) {
 
        printf("QRcode_encodeString failed\n");
 
        return NULL;
 
    }
 
 
 
    qr_w = qrcode->width;
 
    if(width > qr_w) {
 
        qr_pixel_width = width / qr_w;
 
    }
 
 
 
    src_buf_size = qr_w * qr_w * qr_pixel_width * qr_pixel_width * sizeof(lv_color_t);
 
    dst_buf_size = width * width * 2;
 
 
 
    lv_color_t *orig_color_map = lv_mem_aligned_alloc(src_buf_size, 32);
 
    if(orig_color_map == NULL) {
 
        printf("qrcode_gen, no memory 1!!\n");
 
        goto err;
 
    }
 
    memset(orig_color_map, 0x00, src_buf_size);
 
 
 
    qr_data = qrcode->data;
 
    printf("qr width: %d\n", qrcode->width);
 
    int p1;
 
    for (int y = 0; y < qr_w; y++) {
 
        for (int x = 0; x < qr_w; x++) {
 
            idx = y*qr_w + x;
 
            p1 = y * qr_w * (qr_pixel_width * qr_pixel_width) + x * qr_pixel_width;
 
            if ((qr_data[idx] & 0x1) == 0) { /* white pix */
 
                int i = 0;
 
                int p2 = p1;
 
                for(i = 0; i < qr_pixel_width; i++) {
 
                    memset(&orig_color_map[p2], 0xff, sizeof(lv_color_t) * qr_pixel_width);
 
                    p2 += (qr_w * qr_pixel_width);
 
                }
 
            }
 
        }
 
    }
 
 
 
    lv_color_t *dst_color_map = lv_mem_aligned_alloc(dst_buf_size, 32);
 
    if(dst_color_map == NULL) {
 
        printf("qrcode_gen, no memory 2!!\n");
 
        lv_mem_aligned_free(orig_color_map);
 
        goto err;
 
    }
 
 
 
    if(rgb565_scale(qr_w * qr_pixel_width, qr_w * qr_pixel_width, width, width, (uint8_t *)orig_color_map, (uint8_t *)dst_color_map) == 0) {
 
        lv_mem_aligned_free(orig_color_map);
 
        lv_mem_aligned_free(dst_color_map);
 
        goto err;
 
    }
 
 
 
    lv_img_dsc_t *img_des = lv_mem_alloc(sizeof(lv_img_dsc_t));
 
    if(img_des == NULL) {
 
        printf("qrcode_gen, no memory 3!!\n");
 
        lv_mem_aligned_free(orig_color_map);
 
        lv_mem_aligned_free(dst_color_map);
 
        goto err;
 
    }
 
    memset(img_des, 0 , sizeof(lv_img_dsc_t));
 
    img_des->header.w = width;
 
    img_des->header.h = width;
 
    img_des->header.cf = LV_IMG_CF_TRUE_COLOR;
 
    img_des->data_size = dst_buf_size;
 
    img_des->data = (const uint8_t *)dst_color_map;
 
 
 
    lv_obj_t *img = lv_img_create(par, NULL);
 
    lv_img_set_src(img, img_des);
 
 
 
    lv_obj_set_pos(img, px, py);
 
    if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(img);
 
    /*The signal and design functions are not copied so set them here*/
 
    lv_obj_set_signal_func(img, qrcode_signal);
 
 
 
    QRcode_free(qrcode);
 
    lv_mem_aligned_free(orig_color_map);
 
    return img;
 
err:
 
    QRcode_free(qrcode);
 
    printf("qrcode_gen failed\n");
 
    return NULL;
 
}

4、总结

本文讲解了二维码的发展史,已经二维码和条形码的区别,并详细的说明如何在LittlevGL中扩展对条形码及二维码的支持。

开发者支持

如需更多技术支持,可加入钉钉开发者群,或者关注微信公众号。

image.png

更多技术与解决方案介绍,请访问HaaS官方网站https://haas.iot.aliyun.com

相关文章
|
5月前
|
XML 搜索推荐 Java
Android App开发之自定义图形中位图与图形互转、剪裁图形内部区域、给图形添加部件的讲解及实战(附源码 简单易懂)
Android App开发之自定义图形中位图与图形互转、剪裁图形内部区域、给图形添加部件的讲解及实战(附源码 简单易懂)
57 0
|
2月前
|
开发框架 API 开发者
Flutter表单控件深度解析:从基本构建到高级自定义,全方位打造既美观又实用的移动端数据输入体验,让应用交互更上一层楼
【8月更文挑战第31天】在构建美观且功能强大的移动应用时,表单是不可或缺的部分。Flutter 作为热门的跨平台开发框架,提供了丰富的表单控件和 API,使开发者能轻松创建高质量表单。本文通过问题解答形式,深入解读 Flutter 表单控件,并通过具体示例代码展示如何构建优秀的移动应用表单。涵盖创建基本表单、处理表单提交、自定义控件样式、焦点管理和异步验证等内容,适合各水平开发者学习和参考。
28 0
|
2月前
|
C# 开发者 数据处理
WPF开发者必备秘籍:深度解析数据网格最佳实践,轻松玩转数据展示与编辑大揭秘!
【8月更文挑战第31天】数据网格控件是WPF应用程序中展示和编辑数据的关键组件,提供排序、筛选等功能,显著提升用户体验。本文探讨WPF中数据网格的最佳实践,通过DevExpress DataGrid示例介绍其集成方法,包括添加引用、定义数据模型及XAML配置。通过遵循数据绑定、性能优化、自定义列等最佳实践,可大幅提升数据处理效率和用户体验。
49 0
|
5月前
|
Java 数据安全/隐私保护
SpringBoot【集成Thumbnailator】Google开源图片工具缩放+区域裁剪+水印+旋转+保持比例等(保姆级教程含源代码)
SpringBoot【集成Thumbnailator】Google开源图片工具缩放+区域裁剪+水印+旋转+保持比例等(保姆级教程含源代码)
232 0
|
移动开发 JSON API
h5调起原生分享面板,展示更多功能方案
h5调起原生分享面板,展示更多功能方案
259 0
|
自然语言处理 JavaScript 前端开发
动态滑动图片验证码组件(支持多语言,移动端)
动态滑动图片验证码组件(支持多语言,移动端)
动态滑动图片验证码组件(支持多语言,移动端)
|
存储 JavaScript 数据可视化
项目要求移动端适配和 分段视觉映射在ECharts框架里的运用【高级ECharts技术】
项目要求移动端适配和 分段视觉映射在ECharts框架里的运用【高级ECharts技术】
项目要求移动端适配和 分段视觉映射在ECharts框架里的运用【高级ECharts技术】
Flutter如何将文本与图片混合编辑?(功能扩展篇)
一个优秀的富文本,应该包含优秀的排版算法、丰富的功能和渲染的高性能。在上一篇中,我们实现了可扩展的、基础的富文本编辑器。那么在本文中,让我们对富文本进行更多功能的扩展。
Flutter如何将文本与图片混合编辑?(功能扩展篇)
|
Web App开发 移动开发 前端开发
前端基础知识概述 -- 移动端开发的屏幕、图像、字体与布局的兼容适配 (下)
前端基础知识概述 -- 移动端开发的屏幕、图像、字体与布局的兼容适配 (下)
350 0
前端基础知识概述 -- 移动端开发的屏幕、图像、字体与布局的兼容适配 (下)
|
Web App开发 编解码 移动开发
前端基础知识概述 -- 移动端开发的屏幕、图像、字体与布局的兼容适配 (上)
前端基础知识概述 -- 移动端开发的屏幕、图像、字体与布局的兼容适配
315 0
前端基础知识概述 -- 移动端开发的屏幕、图像、字体与布局的兼容适配 (上)
下一篇
无影云桌面