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

相关文章
|
17天前
|
UED 开发者 容器
鸿蒙next版开发:ArkTS组件通用属性(背景设置)
在HarmonyOS 5.0中,ArkTS提供了多种背景设置属性,如backgroundColor、backgroundImage、backgroundSize、backgroundPosition和backgroundBlurStyle,允许开发者自定义组件的背景样式,提升应用的视觉效果和用户体验。本文详细解读了这些属性,并提供了示例代码进行说明。
54 5
|
17天前
|
UED 开发者
鸿蒙next版开发:ArkTS组件通用属性(图片边框设置)
在HarmonyOS 5.0中,ArkTS提供了灵活的图片边框设置属性,使开发者可以为应用中的图片组件添加各种边框效果,提升视觉效果和用户体验。本文详细解读了ArkTS中图片边框设置的通用属性,并提供了示例代码。通过设置`borderImage`属性,可以控制边框的图源、切割宽度、边框宽度、延伸距离、平铺模式和是否填充。示例代码展示了如何使用这些属性来创建具有不同边框效果的图片组件。图片边框设置在美化界面、区分内容和增强交互方面有重要作用。
41 5
|
19天前
|
开发者
鸿蒙next版开发:ArkTS组件通用属性(图形变换)
在HarmonyOS 5.0中,ArkTS提供了强大的图形变换功能,支持组件的旋转、缩放和平移操作,增强用户界面的视觉效果和交互体验。本文详细解读了ArkTS中图形变换的通用属性,并提供了示例代码,包括基础变换、组合变换和动画效果的应用。通过这些示例,开发者可以轻松实现复杂的视觉效果和动态用户界面。
90 1
|
19天前
|
开发者 UED 容器
鸿蒙next版开发:ArkTS组件通用属性(图像效果)
在HarmonyOS 5.0中,ArkTS提供了丰富的图像效果属性,如阴影、灰度、高光、饱和度、对比度、图像反转、叠色、色相旋转等,极大丰富了用户界面的表现力。本文详细介绍这些属性并提供示例代码。
76 2
|
19天前
|
API 开发者 UED
鸿蒙next版开发:ArkTS组件通用属性(形状裁剪)
在HarmonyOS 5.0中,ArkTS引入了形状裁剪的通用属性,支持矩形、圆形、椭圆及自定义路径等多种形状的裁剪和遮罩处理。本文详细解读了clip、clipShape、mask和maskShape属性,并提供了示例代码,帮助开发者实现多样化的界面设计和动画效果。
79 1
|
19天前
|
UED 开发者
鸿蒙next版开发:ArkTS组件通用属性(运动模糊)
在HarmonyOS 5.0中,ArkTS引入了运动模糊功能,允许开发者为组件添加动态模糊效果,增强视觉表现。本文详细解读了运动模糊的属性和使用方法,并提供了示例代码。运动模糊可增强视觉效果、提升用户体验和实现动态效果,适用于多种场景。
101 2
|
19天前
|
开发者 UED 容器
鸿蒙next版开发:ArkTS组件通用属性(栅格设置)
在HarmonyOS 5.0中,ArkTS的栅格系统提供了强大的布局能力,使界面设计更加灵活和响应式。本文详细解读了ArkTS中栅格设置的通用属性,如useSizeType、gridSpan和gridOffset,并通过示例代码展示了如何使用这些属性来创建响应式布局。
73 1
|
3月前
|
C# 开发者 数据处理
WPF开发者必备秘籍:深度解析数据网格最佳实践,轻松玩转数据展示与编辑大揭秘!
【8月更文挑战第31天】数据网格控件是WPF应用程序中展示和编辑数据的关键组件,提供排序、筛选等功能,显著提升用户体验。本文探讨WPF中数据网格的最佳实践,通过DevExpress DataGrid示例介绍其集成方法,包括添加引用、定义数据模型及XAML配置。通过遵循数据绑定、性能优化、自定义列等最佳实践,可大幅提升数据处理效率和用户体验。
62 0
|
存储 JavaScript 数据可视化
项目要求移动端适配和 分段视觉映射在ECharts框架里的运用【高级ECharts技术】
项目要求移动端适配和 分段视觉映射在ECharts框架里的运用【高级ECharts技术】
项目要求移动端适配和 分段视觉映射在ECharts框架里的运用【高级ECharts技术】
Flutter如何将文本与图片混合编辑?(功能扩展篇)
一个优秀的富文本,应该包含优秀的排版算法、丰富的功能和渲染的高性能。在上一篇中,我们实现了可扩展的、基础的富文本编辑器。那么在本文中,让我们对富文本进行更多功能的扩展。
Flutter如何将文本与图片混合编辑?(功能扩展篇)
下一篇
无影云桌面