LVGL-BMP,PNG,JPEG,GIF
- ■ BMP
- ■ 演示一:
- ■ PNG
- ■ 演示一:
- ■ JPEG
- ■ 演示一:
- ■ GIF
- ■ 演示一:
■ BMP
使用 LVGL BMP解码库之前 ,必须在 lv_conf.h文件启用 LV_USE_BMP。
如果该宏定义设置为 1,则启用 BMP 解码库,否则不启用该解码库。
LVGL BMP 解码库的局限性:
(1) BMP 文件只能从文件加载。如果想将它们存储在闪存中,最好使用 LVGL 的图像转换
器将它们转换为 C 数组。
(2) BMP 文件的颜色格式必须与 LV_COLOR_DEPTH 匹配。使用 GIMP 以所需的格式保存
图像,例如我们正点原子的 tft显示屏支持 16位深度的,所以 LV_COLOR_DEPTH设置为 16。
(3) 不支持调色板,简单来讲:不支持图像修改颜色。
■ 演示一:
typedef struct
{char *img_path;char *label_text;
}img_info_t;static const img_info_t draw_img[] =
{{"0:/PICTURE/BMP/camera.bmp", "camera"},{"0:/PICTURE/BMP/ALIENTEKLOGO.bmp", "ALIENTEKLOGO"},
};
#define img_Num sizeof(draw_img) / sizeof(draw_img[0])lv_obj_t *img;
img = lv_img_create(lv_scr_act()); /* 创建图像 */
lv_img_set_src(img, draw_img[0].img_path); /* 设置图像源 */
lv_obj_align_to(img, NULL, LV_ALIGN_CENTER, 0, 0);/* 设置对齐模式 */
■ PNG
PNG 是一种采用无损压缩算法的位图格式,
其设计目的是试图替代 GIF 和 TIFF 文件格式
增加一些 GIF 文件格式所不具备的特性。
PNG 使用从 LZ77 派生的无损数据压缩算法。
使用 LVGL PNG解码库之前,必须在 lv_conf.h 文件启用 LV_USE_PNG宏定义。
如果该宏定义设置为 1,则启用 PNG 解码库,否则不启用该解码库。
■ 演示一:
/* PNG 图片结构体 */
typedef struct
{char *img_path; /* 图片路径 */char *label_text; /* 图片名称 */
}img_info_t;
/* 定义 PNG 路径 */
const img_info_t PNG_PATH[] =
{{"0:/PICTURE/PNG/mlljt.png", "xiaomao.png"},{"0:/PICTURE/PNG/laji.png", "laji.png"},
};/* 获取路径的个数 */
#define image_mun (int)(sizeof(PNG_PATH)/sizeof(PNG_PATH[0]))
lv_obj_t *img;/**
* @brief 创建 PNG 图片文件
* @param parent:父类
* @param path: 图片路径
* @retval 返回图片部件
*/
lv_obj_t * lv_png_create_from_file(lv_obj_t * parent, const char * path)
{lv_obj_t * img = lv_img_create(parent);lv_img_set_src(img, path);lv_obj_align_to(img,NULL,LV_ALIGN_CENTER,0,0);return img;
}
/**
* @brief LVGL 程序入口
* @param 无
* @retval 无
*/
void lv_mainstart()
{lv_png_init(); /* 初始化 PNG 解码库 */lv_obj_t *label = lv_label_create(lv_scr_act());lv_label_set_text(label,"PNG_Decoder");lv_obj_align_to(label,NULL,LV_ALIGN_TOP_MID,0,0);/* 创建 PNG 文件 */img = lv_png_create_from_file(lv_scr_act(),PNG_PATH[0].img_path);
}
■ JPEG
打开 lv_conf.h 文件, 然后在该文件找到 LV_USE_SJPG 宏定义并设置为 1 启用 JPEG
解码库,该解码库的初始化在 lv_init/lv_extra_init 函数下调用 lv_split_jpeg_init 函数。
官方对 LVGL 的 JPEG 解码器概述:
① 该解码库支持常规 jpg 和自定义 sjpg 格式。
② 解码普通 jpg 会占用整个未压缩图像内存(建议用于具有更多 RAM 的设备) 。
③ sjpg 是基于“普通” JPG 的自定义格式,是为 lvgl 专门制作的。
④ sjpg 是“ split-jpeg”,它是一堆带有 sjpg 标头的小 jpeg 片段。
⑤ sjpg 大小将几乎与 jpg 文件相当,或者可能稍大。
⑥ 从磁盘(读取)和 c 数组读取实现。
⑦ 如果在缓存中可用,则 SJPEG 帧片段缓存可实现行的快速获取。
⑧ 默认情况下, sjpg 图像缓存为图像宽度 * 2 * 16 字节(可以修改) 。
⑨ 当前仅支持 16 位图像格式(可做) 。
⑩ JPG 和 SJPG 图像只解码所需的部分,因此不能缩放或旋转
LVGL 解码库支持三种读取 jpeg 方式, 这三种方式如下所示:
① 将 JPG 转换为 C 数组,使用在线图片软件转换即可,注意: Color format = RAW, output
format = C Array 选项配置。
② SJPG 图片格式读取,这类不是我们涉及的领域,但是我们 MCU 可以读取这类型的图
片格式, SJPG 图片格式使用 JPG 图片经过 python3 和 PIL 库进行转换。
③ 直接使用 LVGL 文件系统读取 SD 卡路径下的 jpeg 图片。
JPG 转换 SJPG 图片格式
JPG 转换 SJPG 图片格式需要 python3 和 PIL 库,首先我们下载
python 软件安装,打开网址: https://www.python.org/downloads/, 然后点击下载,
■ 演示一:
/**
* @brief lvgl 程序入口
* @param 无
* @retval 无
*/
void lv_mainstart()
{/* 创建标签 */lv_obj_t *label = lv_label_create(lv_scr_act());/* 设置标签颜色 */lv_label_set_text(label,"JPEG_Decoder");/* 设置文本颜色 */lv_obj_set_style_text_color(label,lv_palette_main(LV_PALETTE_RED), LV_STATE_DEFAULT);/* 设置文本字体 */lv_obj_set_style_text_font(label,&lv_font_montserrat_32,LV_STATE_DEFAULT);/* 设置顶部中间对齐 */lv_obj_align(label,LV_ALIGN_TOP_MID,0,0);/* 设置背景颜色 */lv_obj_set_style_bg_color(lv_scr_act(),lv_palette_main(LV_PALETTE_BLUE), LV_STATE_DEFAULT);/* 创建 image 部件 */lv_obj_t * img = lv_img_create(lv_scr_act());/* 设置图像源 */lv_img_set_src(img, "0:/PICTURE/JPEG/SIM900A.jpg");/* 中间对齐 */lv_obj_align(img,LV_ALIGN_CENTER,0,0);
}
■ GIF
使用 LVGL GIF解码库之前,必须在 lv_conf.h文件启用 LV_USE_GIF。如果该宏定义设置为 1,则启用 GIF 解码库,否则不启用该解码库。
小知识:
GIF 图像被解码时,在解码过程中所需要 RAM 是以颜色深度决定的。
(1) LV_COLOR_DEPTH 为 8,则所需要的 RAM 为宽度高度3 内存。
(2) LV_COLOR_DEPTH 为 16,则所需要的 RAM 为宽度高度4 内存。
(3) LV_COLOR_DEPTH 为 32,则所需要的 RAM 为宽度高度5 内存。
例如, 颜色深度为 16 的一个 800480 的 GIF图像,它所需要的 RAM 为 800480*4(约等于
1.4M)内存。
GIF 读取方案:
LVGL GIF 解码库读取具有两种方案,第一个是把 GIF 转成 C 数组格式文件, 而另一种就
是文件系统读取。
注意: 如果 GIF 图像使用官方在线转换工具, 则有 Color format 选择颜色格式(RAW)。
■ 演示一:
typedef struct
{char *img_path;char *label_text;
}img_info_t;
const img_info_t GIF_PATH[] =
{{"0:/PICTURE/GIF/alientek.gif", "alientek.gif"},
};#define image_mun (int)(sizeof(GIF_PATH)/sizeof(GIF_PATH[0]))
int image = 0;
lv_obj_t *img;
static lv_style_t img_style;
extern int has_next;
void lv_mainstart(void)
{lv_obj_t *label;label = lv_label_create(lv_scr_act());lv_label_set_text(label,"GIF_Decoder");lv_obj_set_style_text_color(label, lv_palette_main(LV_PALETTE_RED),LV_STATE_DEFAULT);lv_obj_set_style_text_font(label,&lv_font_montserrat_32,LV_STATE_DEFAULT);lv_obj_align_to(label,NULL,LV_ALIGN_TOP_MID,0,0);lv_obj_set_style_bg_color(lv_scr_act(),lv_palette_main(LV_PALETTE_BLUE),LV_STATE_DEFAULT);lv_obj_set_style_bg_color(lv_scr_act(),lv_palette_main(LV_PALETTE_BLUE),LV_STATE_DEFAULT);img = lv_gif_create(lv_scr_act());lv_gif_set_src(img, GIF_PATH[image].img_path);lv_obj_align_to(img,NULL,LV_ALIGN_CENTER,0,0);lv_timer_create(lv_my_timer,10,img);
}void lv_my_timer(lv_timer_t *timer)
{if (has_next == 0) /* 如果是最后一帧,那么切换 GIF */{image++;lv_obj_del(img); /* 删除前面的 GIF */if (image >= image_mun) /* 判断 GIF 库包含的个数是否最大 */{image = 0; /* 重新开始展示 */img = lv_gif_create(lv_scr_act());lv_gif_set_src(img, GIF_PATH[image].img_path);}else /* 如果不是最后的 GIF */{img = lv_gif_create(lv_scr_act());lv_gif_set_src(img, GIF_PATH[image].img_path);}timer->user_data = img; /* 设置任务数据等于获取的图片数据 */lv_obj_align_to(img,NULL,LV_ALIGN_CENTER,0,0);}
}