LVGL库入门 04 - 颜色与图像

news2024/11/25 20:36:52

1、颜色

1.1、构造颜色

在 LVGL 中,颜色以结构 lv_color_t 表示。在最开始移植整个工程时,曾经在 lv_conf.h 中修改过颜色深度:

/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
#define LV_COLOR_DEPTH 32

LVGL 会自动根据所选的颜色深度创建合适的颜色结构。在接下来几处位置还有几个与颜色有关的配置选项,可以参照注释修改。

例如,16 位 big-endian 的颜色定义为:

typedef union {
    struct {
        uint16_t blue  : 5;
        uint16_t green : 6;
        uint16_t red   : 5;
    } ch;
    uint16_t full;
} lv_color16_t;
typedef lv_color16_t lv_color_t;

那么就可以根据该结构创建合适的颜色值了:

lv_color_t orange = {
    .ch = {
        .red   = 0b11111,
        .green = 0b101001,
        .blue  = 0
    }
};

直接创建 RGB565 的颜色格式有点难以调色,不过可以借用以下函数从十六位颜色中生成合适的颜色值:

lv_color_t orange = lv_color_make(0xFF, 0xA5, 0);  // 从颜色通道创建
lv_color_t aqua = lv_color_hex(0x00FFFF);          // 从十六进制创建
lv_color_t lightgrey = lv_color_hex3(0xddd);       // 从十六进制简写创建

这些颜色在创建时,每种颜色通道的值都使用 0~255 表示即可,创建过程中会自动转换为合适的颜色值。

LVGL 还提供了 HSV 格式的颜色支持,

lv_color_t red = lv_color_hsv_to_rgb(0, 100, 100);   // 从 HSV 颜色空间创建颜色
lv_color_hsv_t blue = lv_color_rgb_to_hsv(r, g, b);  // 将 RGB 颜色转换为 HSV 颜色

除此之外,lv_color_t 、RGB 颜色、HSV 颜色之间也能互相转换。


如果觉得 16 进制的颜色还是不够直观,还可以使用调色板功能。LVGL 提供了常用颜色的色值表示,可以直接使用、微调、混合这些颜色。

例如,以下直接调出了一个紫色:

lv_color_t purple = lv_palette_main(LV_PALETTE_PURPLE)

如果觉得默认的紫色太深或太浅的话,还可以在调色板中更改亮度:

lv_color_t dark_purple = lv_palette_darken(LV_PALETTE_PURPLE, 2)  // 调深两级,最多可以调深或浅 4 级
lv_color_t light_purple = lv_color_lighten(purple, 60);  // 调浅一些,调到 255 就变成纯白

甚至还可以将两种颜色混合:

lv_color_t orange = lv_color_mix(red, yellow, 156);

比例的取值为 0~255 ,例如设定为 0 就是全红,128 就是红黄各占一半等。

可以将一个颜色类型直接应用到以下样式属性中:

属性名含义
bg_color背景颜色
border_color边框颜色
outline_color轮廓颜色
shadow_color阴影颜色
text_color文本颜色

以及上一节提到的直线和弧线颜色。

1.2、透明度

有时候两个控件间可能发生重叠,这个时候就可以给它们设置一个透明度。

透明度使用类型 lv_opa_t 表示,LVGL 预定义了几个表示透明度的宏:LV_OPA_TRANSP 表示完全透明,LV_OPA_COVER 表示完全不透明,其余的 LV_OPA_10 LV_OPA_90 整十表示的透明度依次递减。

可以将透明度应用到以下样式属性中:

属性名含义
bg_opa背景透明度
border_opa边框透明度
outline_opa轮廓透明度
shadow_opa阴影透明度
text_opa文本透明度
opa整体透明度

以及直线和弧线透明度。例如,以下创建了两个部分重叠的控件,并在一个的背景上加透明度:

static lv_style_t style_grass;
lv_style_init(&style_grass);
lv_style_set_opa(&style_grass, LV_OPA_30);
lv_obj_t* obj = lv_obj_create(lv_scr_act());
lv_obj_t* cover = lv_obj_create(lv_scr_act());
lv_obj_add_style(cover, &style_grass, 0);

这样就可以看见被遮挡的控件了:

image

注意需要给上层,即后创建的的控件加透明度才会有这样的效果。透明度其实就是为控件重新调色,因此不是 32 位颜色的屏幕也可以使用透明度。

lv_opa_t 类型的本质就是 8 位无符号整数,因此可以自行创建一个透明度数值,设为 255 就代表完全透明;还可以将透明度应用到 lv_color_mix() 的第三个参数上。

1.3、渐变色

可以使用渐变色给控件加上更美观的效果。

只有背景颜色能设置渐变色。一个渐变色的效果由以下几个属性支配:

属性名含义
bg_color主要颜色
bg_grad_color渐变颜色
bg_grad_dir渐变方向
bg_main_stop渐变开始位置
bg_grad_stop渐变结束位置
bg_dither_mode渲染模式

当确定了渐变方向后,渐变从 bg_main_stop 位置开始,由 bg_color 过度到 bg_grad_color ,在 bg_grad_stop 位置结束。这里的位置是由比例衡量的,渐变区域在每个方向都被划分为 256 份,例如 128 代表中间位置,255 代表结束位置等。

例如,以下代码:

lv_obj_t* obj01 = lv_obj_create(lv_scr_act());
lv_obj_set_style_bg_color(obj01, lv_palette_main(LV_PALETTE_BLUE), 0);
lv_obj_set_style_bg_grad_color(obj01, lv_palette_main(LV_PALETTE_RED), 0);
lv_obj_set_style_bg_grad_dir(obj01, LV_GRAD_DIR_HOR, 0);

渐变效果为水平方向从蓝色一直渐变到红色:

image

再如,以下代码:

lv_obj_t* obj02 = lv_obj_create(lv_scr_act());
lv_obj_set_style_bg_color(obj02, lv_palette_main(LV_PALETTE_GREEN), 0);
lv_obj_set_style_bg_grad_color(obj02, lv_palette_main(LV_PALETTE_PURPLE), 0);
lv_obj_set_style_bg_grad_stop(obj02, 128, 0);
lv_obj_set_style_bg_grad_dir(obj02, LV_GRAD_DIR_VER, 0);

渐变效果为竖直方向从绿色一直渐变到紫色,但实际渐变区域只有上半部分:

image

还可以使用简写属性 bg_grad 设置完整的渐变属性。这种情况下,渐变使用结构 lv_grad_dsc_t 描述:

typedef struct {
    lv_gradient_stop_t stops[LV_GRADIENT_MAX_STOPS];
    uint8_t            stops_count;
    lv_grad_dir_t      dir    : 3;
    lv_dither_mode_t   dither : 3;
} lv_grad_dsc_t;

宏 LV_GRADIENT_MAX_STOPS 决定了最大拥有的渐变颜色数,可以在 lv_conf_internal.h 大约 377 行修改该宏的数量:

#ifndef LV_GRADIENT_MAX_STOPS
    #ifdef CONFIG_LV_GRADIENT_MAX_STOPS
        #define LV_GRADIENT_MAX_STOPS CONFIG_LV_GRADIENT_MAX_STOPS
    #else
        #define LV_GRADIENT_MAX_STOPS 3
    #endif
#endif

然后就可以自定义多种颜色的渐变了:

static lv_grad_dsc_t grad_sunset;
grad_sunset.stops[0] = (lv_gradient_stop_t){ .color = lv_palette_main(LV_PALETTE_RED), .frac = 96 };
grad_sunset.stops[1] = (lv_gradient_stop_t){ .color = lv_palette_main(LV_PALETTE_ORANGE), .frac = 128 };
grad_sunset.stops[2] = (lv_gradient_stop_t){ .color = lv_palette_main(LV_PALETTE_BLUE), .frac = 216 };
grad_sunset.stops_count = 3;
grad_sunset.dir = LV_GRAD_DIR_VER;
lv_obj_t* obj03 = lv_obj_create(lv_scr_act());
lv_obj_set_style_bg_grad(obj03, &grad_sunset, 0);

效果为:

image

1.4、颜色的其它内容

LVGL 还提供了许多处理颜色的滤镜。可以使用样式属性 blend_mode 设置颜色和背景色的融合。例如,以下将控件的颜色设置为背景色的反色:

lv_obj_set_style_blend_mode(obj03, LV_BLEND_MODE_SUBTRACTIVE, 0);

效果为:

image

注意边框的颜色也变成反色了。

最后,LVGL 中还要一个控件 color wheel ,可以快速创建一个颜色选择器。它的默认表现形式为:

image

它类似于圆弧,并可以通过长按切换模式。可以使用函数 lv_colorwheel_get_rgb() 获取当前选择的颜色。

2、图片

2.1、创建图片

图片可以以两种方式存储:一是作为一个数组之类的变量,二是通过二进制文件的形式存储。由于还没有介绍文件相关的内容,这里仅介绍使用数组的方式来存储并使用图片。

LVGL 已经提供了在线图片转换器,可以直接在 Online image converter - BMP, JPG or PNG to C array or binary | LVGL 将一般的 PNG 或 JPG 图片转换为符合要求的 C 语言对象:

image

注意转换完成后得到的是一个完整的源文件,文件名同时也是图片的变量名。以上唯一值的注意的一点是图片所用的颜色格式,一般来说颜色格式可以分为以下几类:

  1. True color :自动适配当前项目使用的颜色深度
  2. Indexed :从调色板创建较少的颜色数目
  3. Alpha only :单色图像,只使用透明度
  4. Raw :使用图像原本的颜色格式

最后一个 RBG565-A8 就不必多说了。值的注意的是,以上有一种叫“Chroma key” 的颜色格式,它对应 lv_conf.h 的第 42 行的配置,注释是这样说的:

/*Images pixels with this color will not be drawn if they are chroma keyed)*/
#define LV_COLOR_CHROMA_KEY lv_color_hex(0x00ff00)         /*pure green*/

更多有关于此的介绍可以阅读维基百科 https://en.wikipedia.org/wiki/Chroma_key

转换完成后,将得到的源文件添加到当前工程内,然后通过以下几行代码就可以显示该图像:

LV_IMG_DECLARE(lvgl_logo);
lv_obj_t* img01 = lv_img_create(lv_scr_act());
lv_img_set_src(img01, &lvgl_logo);

这里第一个宏的作用本质就是一个 extern 语句。显示的效果为:

image

注意这里在模拟器上创建的图片是具有透明度的。

2.2、图片的属性

像直线和圆弧一样,图片对象也是有特殊的属性的,不过比较少:

属性简介
img_opa图片透明度
img_recolor可以给图片加上一层颜色滤镜
img_recolor_opa这层滤镜的透明度

默认情况下,图片控件会自动调整宽度以适应图片大小。如果控件过小,那么图片的额外部分会被去除;如果控件过大,那么图片会像地砖一样重复铺开来填补剩下的区域。

可以通过 lv_img_set_offset_x(img, x_ofs) 与 y 轴对应的函数给图片设置一个偏移量来修改显示范围。例如,可以通过偏移量结合控件宽度来裁剪图片:

lv_img_set_offset_x(img01, -2);
lv_img_set_offset_y(img01, -7);
lv_obj_set_size(img01, 74, 74);

这里通过负值来将图片向左上角偏移,从而框选出合适的区域:

image

2.3、图片按钮

最后再介绍一个内容,可以通过图片来创建一个按钮。这种情况下,需要准备三张图片,分别描述按钮的左边、中间和右边。

例如,以下准备图片如下:

image

 

image

 

image

由于标签的宽度是不确定的,因此中间的图片必须是水平可平铺的。将其转换为对应的图片格式后,可以通过以下代码创建一个图片按钮:

lv_obj_t* imgbtn = lv_imgbtn_create(lv_scr_act());
lv_imgbtn_set_src(imgbtn, LV_IMGBTN_STATE_RELEASED, &imgbtn_left, &imgbtn_mid, &imgbtn_right);
lv_obj_t* label = lv_label_create(imgbtn);
lv_label_set_text(label, "Image Button");
lv_obj_set_style_img_recolor_opa(imgbtn, LV_OPA_30, LV_STATE_PRESSED);
lv_obj_set_style_img_recolor(imgbtn, lv_color_black(), LV_STATE_PRESSED);

注意在创建的过程中,将以上图片应用到按钮的普通状态(即什么事件都没有的状态)的外观中。这里通过给点击事件加上一层深色的滤镜使点击时外观可以发生改变:

image

这样按钮就可以变得很花哨了。

以上对于图片的介绍比较简单,不过也基本足以应付一般的使用场景了。更多细节可以参考官方文档。

3、参考资料/延伸阅读

Colors — LVGL documentation

颜色参考文档

https://docs.lvgl.io/master/overview/image.html
https://docs.lvgl.io/master/widgets/core/img.html

有关图片及图片控件的完整使用描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1162681.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用 javascript 在 n*m 网格中演示 BFS 广度优先搜索算法在带权重图中求最短路径

普通的广度优先最短路径搜索算法只能解决无权重的图: 求出的最短路径没问题,但是如果上边的空缺格子的距离为100呢?这种方式搜出的最短路径可能就是错的: 我们可以找一个距离1作为基本距离,然后距离为100的格子在搜索时…

[免费] 适用于 Windows的10 的十大数据恢复软件

Windows 10是微软开发的跨平台和设备应用程序的操作系统。它启动速度更快,具有熟悉且扩展的“开始”菜单,甚至可以在多种设备上以新的方式工作。所以,Windows 10非常流行,我们用它来保存我们的照片、音乐、文档和更多文件。但有时…

高效剪辑:视频剪辑新手如何批量分割视频

随着社交媒体和自媒体的兴起,视频剪辑已经成为一项必备的技能。无论是制作自己的电影、视频博客,还是为广告宣传提供支持,高效地剪辑视频都是非常重要的。对于视频剪辑新手来说,了解如何批量分割视频是提高剪辑效率的关键。本文讲…

左右联动 provide、inject+props、emit

实现效果 成都大屏 —— 视频管理 左右两个都是组件,所以涉及到父组件向多个子组建传递数据 方法1 provide、inject 目录结构 父组件 index.vue 用provide传递数据和修改数据的方法 import { provide} from "vue"; provide("Provide_Selected…

C语言队列实现

1.知识百科 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的…

月入8K, 计算机专业应届女孩转行5G网络优化工程师,她说:这行请慎入

小C说,如果要用两个字描述23年计算机专业的就业心情,那就是“焦虑”;用三个字描述23年计算机专业的就业环境,那就是“卷麻了”。 得益于张雪峰老师的就业推荐计算机专业需求的日益减少,2023年,计算机专业成…

【漏洞复现】74cms任意文件读取

漏洞描述 74CMS 是一款国内用的比较多招聘网站管理系统(Job Board CMS),专注于招聘和人力资源领域的网站建设,存在任意文件读取漏洞 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律&#xff0c…

vue3中使用deck.gl

deck,gl网址:Home | deck.gl 因为deck.gl是国外的技术,国外最流行的框架是react,所以deck.gl有为react提供的地图组件,没有为vue提供,并且还需要翻墙。所以想用vue使用这个还是有一定难度的。 除了用到deck.gl之外还…

使用Serv-U FTP服务器共享文件,实现无公网IP的外网访问

文章目录 1. 前言2. 本地FTP搭建2.1 Serv-U下载和安装2.2 Serv-U共享网页测试2.3 Cpolar下载和安装 3. 本地FTP发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1. 前言 科技日益发展的今天,移动电子设备似乎成了我们生活的主角,智能…

vue项目打包时按一定的名称规范生成对应的压缩包

在项目部署中经常需要将打包的dist按一定的名称压缩成压缩包,今天记录一下打包时生成压缩包的过程。其中有用到的npm包需要自己安装一下。 js文件放置的目录如下 compress.js内容如下: // compress.jsimport fs from "fs"; import shell fro…

电商价格数据监测接口|淘宝商品价格接口|天猫商品价格接口|京东商品价格接口|拼多多商品价格接口|API接口申请指南

电商价格数据监测接口是一种可以实时监测电商平台上商品价格的接口工具。通过这个接口,可以获取到各个电商平台的商品价格信息,并且可以设置价格监控频率、智能数据绑定、破价提醒机制等功能。 以下是电商价格数据监测接口的一些特点: 商城…

“恒山光量子”首秀!玻色量子联合移动云发表物理1区Top期刊SCPMA论文

2023年5月,北京玻色量子科技有限公司(以下简称“玻色量子”)联合移动云在我国知名科技期刊平台《中国科学:物理学 力学 天文学》英文版上发表了以“Optical experimental solution for the multiway number partitioning problem …

网络工程师进阶课:华为HCIP认证课程介绍

微思网络HCIP VIP试听课程:DHCP协议原理与配置https://www.bilibili.com/video/BV1cy4y1J7yg/?spm_id_from333.999.0.0 【微|信|公|众|号:厦门微思网络】 【微思网络http://www.xmws.cn,成立于2002年,专业培训21年,思…

获评AI基础软件「领导者」,九章云极DataCanvas公司技术创新能力最强!

近日,弗若斯特沙利文(Frost & Sullivan,简称“沙利文”)正式发布《中国AI基础软件市场研究报告(2023)》,公布当下对中国AI基础软件发展创新的最新洞察。九章云极DataCanvas公司获评AI基础软…

@所有人,城市燃气信息化与信息安全建设方法

关键词:城市燃气信息化、智慧燃气建设、城市燃气安全、智慧燃气、智慧燃气平台 近几年,燃气作为一种新兴的燃料迅速普及开来,和燃气有关的企业之间的竞争也不可避免。身处在互联网的时代,企业只有顺应时代的潮流,将城…

zookeeper集群选举机制

Zookeeper选举机制——第一次启动 zookeeper集群三个重要的参数(决定选举结果) SID : 服务器 ID 。 用来唯一标识一台 ZooKeeper集群中的机器,每台机器不能重 , 和 myid 一致 。 ZXID :事务 ID 。 ZXID 是…

室内外导航一体化技术原理与成品展示

随着人们对出行需求的不断提升,室内外导航一体化技术变得越来越重要。该技术可以帮助用户在建筑物内、外部空间以及城市范围内进行精确导航,提升出行体验。 室内外一体化导航实现技术原理 室内外导航技术主要依赖于定位技术、地图数据以及空间建模等手段…

YOLOV8 NANO手势识别

采用YOLOV8 NANO训练,得到pt模型,然后转换成ONNX模型,OPENCV DNN调用,支持C,PYTHON,ANDROID开发。CPU每帧20MS左右,可以达到实时性 YOLOV8NANO手势识别

保护隐私,打造独特的个人图床——cpolar+Qchan轻量级搭建——“cpolar内网穿透”

文章目录 前言1. Qchan网站搭建1.1 Qchan下载和安装1.2 Qchan网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar云端设置2.2 Cpolar本地设置 3. 公网访问测试总结 前言 图床作为云存储的一项重要应用场景,在大量开发人员的努力下,已经开发出大…

文言一心中将C语言归类为低级语言,这对么?

文言一心中将C语言归类为低级语言,这对么? 以下是文言一心中的回答:C语言属于低级语言。低级语言通常指的是接近于机器语言的编程语言,它们与计算机硬件的交互更加直接,能够更高效地利用计算机资源。最近很多小伙伴找我&#xff…