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

相关文章
|
达摩院 语音技术 开发工具
达摩院FunASR离线文件转写SDK发布,完成工业落地“最后一公里”
达摩院FunASR离线文件转写SDK发布,完成工业落地“最后一公里”
2167 0
|
4月前
|
前端开发
【大白话前端 10】从页面互跳到锚点定位,关于 <a> 标签最容易被忽视的 5 个实操
HTML中`&lt;a&gt;`标签是网页互联的基石。本文详解5大核心用法:外链(需带`https://`)、内链(相对路径)、新页打开(`target=&quot;_blank&quot;`)、页面锚点(`#id`)、下载/邮件(`download`/`mailto:`),并强调常见误区与速记要点。(239字)
|
12月前
|
存储 机器学习/深度学习 Java
Java 大视界 -- Java 大数据在智慧水利水资源调度与水情预测中的应用创新(180)
本文探讨了Java大数据技术在智慧水利中的创新应用,重点分析了其在水资源调度与水情预测中的关键技术与实践案例。通过大数据存储、实时处理与深度学习模型,Java有效提升了水利数据管理效率与水情预测准确性,助力传统水利向智能化转型。
【LVGL快速入门】LVGL开源框架入门教程之框架使用(三)
【LVGL快速入门】LVGL开源框架入门教程之框架使用(三)
1360 1
【LVGL快速入门】LVGL开源框架入门教程之框架使用(三)
|
缓存 容灾 网络协议
ACK One多集群网关:实现高效容灾方案
ACK One多集群网关可以帮助您快速构建同城跨AZ多活容灾系统、混合云同城跨AZ多活容灾系统,以及异地容灾系统。
|
移动开发 JavaScript 网络协议
SpringBoot:Netty-SocketIO + VUE:SocketIO实现前后端实时双向通信
SpringBoot:Netty-SocketIO + VUE:SocketIO实现前后端实时双向通信
1384 0
游戏辅助 -- 三种分析角色坐标方法(CE、xdbg、龙龙遍历工具)
游戏辅助 -- 三种分析角色坐标方法(CE、xdbg、龙龙遍历工具)
1819 0
|
负载均衡 算法 网络虚拟化
ensp中链路聚合配置命令
链路聚合(Link Aggregation)是结合多条物理链路形成逻辑链路的技术,提升网络带宽、增强冗余性和优化负载均衡。在高带宽、高可靠性及负载均衡需求的场景如服务器集群、数据中心等中广泛应用。配置包括手动和自动模式,手动模式下,如LSW1和LSW2,通过`int eth-trunk`、`trunkport`等命令配置接口和成员链路。自动模式下,如SW3和LSW4,使用LACP协议动态聚合,通过`mode lacp-static`和`load-balance dst-mac`命令设置。配置后,使用`dis eth-trunk`检查聚合状态。
3251 1
ensp中链路聚合配置命令
|
编译器
MDK5.38 + 许可证及 ARM Compiler V5 安装
MDK5.38 + 许可证及 ARM Compiler V5 安装
4104 1
|
设计模式 缓存 Java
从ThreadLocal谈到TransmittableThreadLocal,从使用到原理3
从ThreadLocal谈到TransmittableThreadLocal,从使用到原理
3180 1

热门文章

最新文章