您尚未登录。

楼主 #1 2018-12-01 19:15:43

quop_mike
会员
注册时间: 2018-11-29
已发帖子: 8
积分: 8

研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

LVGL版本是5.2,芯片是ESP32【内核是小端】,FATFS使能长文件名,然后同时使能了CP936(支持中文文件名)
问题来了,做了一个MP3播放器,然后在屏幕上显示正在播放的文件名,显示的文件名除了英文全部乱码
研究了一下,由于使能了CP936,所以FATFS读回来的文件名字串应该就是GBK编码的,但是LVGL不支持GBK编码,所以查不到对应的字库来显示,所以全乱码
刚开始以为LVGL直接支持unicode,把GBK强制转换成unicode以后还是乱码,一脸懵逼
搞了好久才弄清楚,LVGL支持的是UTF-8编码格式,简单来说就是英文是1个byte,中文是3byte,那就好办了
思路如下:
对于英文字符,ASCII和GBK还有UTF-8都是一毛一样的,那么
读GBK的字串中的一个byte
       若值<0x80,那么说明目前读取的就是英文字符,直接copy到输出即可

       若值>=0x80,那么说明读取到的已经不是英文字符了,那么先转换为unicode,然后再把unicode转换为UTF-8编码即可

代码如下,均为小端,大端请自行处理

/*------------------
*gbk 指向gbk字串的指针【输入】
*utf8 指向utf8字串的指针【输出】
--------------------*/
void StringGBK2UTF8(uint8_t *gbk, uint8_t *utf8)
{
	int i = 0;
	while (gbk[i] != 0)
	{
		if (gbk[i] < 0x80)
		{
			*utf8 = gbk[i];
			utf8++;
			i++;
		}
		else
		{
			WCHAR unicode = ff_oem2uni((WCHAR)(gbk[i] << 8 | gbk[i+1]), 936);
			int byte = enc_unicode_to_utf8_one(unicode, utf8);
			utf8 += byte;
			i = i + 2;
		}
	}
}

其中ff_oem2uni是FATFS自带的把相应的CODEPAGE编码字符转换成UNICODE字符的函数,不同版本的函数可能略有区别
enc_unicode_to_utf8_one函数是把一个unicode转换为utf-8编码

int enc_unicode_to_utf8_one(unsigned long unic,unsigned char *pOutput)
{  
	assert(pOutput != NULL);  
  
	if (unic <= 0x0000007F)  
	{  
		// * U-00000000 - U-0000007F:  0xxxxxxx  
		*pOutput     = (unic & 0x7F);  
		return 1;  
	}  
	else if (unic >= 0x00000080 && unic <= 0x000007FF)  
	{  
		// * U-00000080 - U-000007FF:  110xxxxx 10xxxxxx  
		*(pOutput + 1) = (unic & 0x3F) | 0x80;  
		*pOutput     = ((unic >> 6) & 0x1F) | 0xC0;  
		return 2;  
	}  
	else if (unic >= 0x00000800 && unic <= 0x0000FFFF)  
	{  
		// * U-00000800 - U-0000FFFF:  1110xxxx 10xxxxxx 10xxxxxx  
		*(pOutput + 2) = (unic & 0x3F) | 0x80;  
		*(pOutput + 1) = ((unic >>  6) & 0x3F) | 0x80;  
		*pOutput     = ((unic >> 12) & 0x0F) | 0xE0;  
		return 3;  
	}  
	else if (unic >= 0x00010000 && unic <= 0x001FFFFF)  
	{  
		// * U-00010000 - U-001FFFFF:  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx  
		*(pOutput + 3) = (unic & 0x3F) | 0x80;  
		*(pOutput + 2) = ((unic >>  6) & 0x3F) | 0x80;  
		*(pOutput + 1) = ((unic >> 12) & 0x3F) | 0x80;  
		*pOutput     = ((unic >> 18) & 0x07) | 0xF0;  
		return 4;  
	}  
	else if (unic >= 0x00200000 && unic <= 0x03FFFFFF)  
	{  
		// * U-00200000 - U-03FFFFFF:  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx  
		*(pOutput + 4) = (unic & 0x3F) | 0x80;  
		*(pOutput + 3) = ((unic >>  6) & 0x3F) | 0x80;  
		*(pOutput + 2) = ((unic >> 12) & 0x3F) | 0x80;  
		*(pOutput + 1) = ((unic >> 18) & 0x3F) | 0x80;  
		*pOutput     = ((unic >> 24) & 0x03) | 0xF8;  
		return 5;  
	}  
	else if (unic >= 0x04000000 && unic <= 0x7FFFFFFF)  
	{  
		// * U-04000000 - U-7FFFFFFF:  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx  
		*(pOutput + 5) = (unic & 0x3F) | 0x80;  
		*(pOutput + 4) = ((unic >>  6) & 0x3F) | 0x80;  
		*(pOutput + 3) = ((unic >> 12) & 0x3F) | 0x80;  
		*(pOutput + 2) = ((unic >> 18) & 0x3F) | 0x80;  
		*(pOutput + 1) = ((unic >> 24) & 0x3F) | 0x80;  
		*pOutput     = ((unic >> 30) & 0x01) | 0xFC;  
		return 6;  
	}  
  
	return 0;  
}  

离线

#2 2018-12-01 19:42:19

arphone
会员
注册时间: 2017-11-03
已发帖子: 92
积分: 83.5

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

不错,感谢分享!

离线

#3 2018-12-01 20:00:59

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,230
积分: 9197

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

不错,感谢分享!





离线

#4 2018-12-01 20:28:09

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,230
积分: 9197

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑



帮楼主补上视频





离线

#5 2018-12-01 20:29:51

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,230
积分: 9197

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑





离线

#6 2018-12-03 19:08:39

dgtg
会员
注册时间: 2017-11-08
已发帖子: 253
积分: 212.5

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

蛮酷的界面呀...

离线

#7 2019-01-18 20:33:46

jw__liu
会员
注册时间: 2019-01-18
已发帖子: 40
积分: 40

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

正要用啊感谢。

离线

#8 2019-01-23 17:56:39

rpi
会员
注册时间: 2019-01-23
已发帖子: 2
积分: 2

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

不错,感谢分享!

离线

#9 2019-03-10 11:26:49

tink
会员
注册时间: 2019-03-09
已发帖子: 32
积分: 32

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

mark

离线

#10 2019-03-10 13:12:23

Ken
会员
注册时间: 2019-01-06
已发帖子: 58
积分: 58

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

mark. 感谢分享!

离线

#11 2019-09-21 09:51:45

还能这么玩
会员
注册时间: 2019-04-14
已发帖子: 119
积分: 119

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

mark. 感谢分享!

离线

#12 2019-09-22 11:45:21

cjqdot
会员
注册时间: 2019-09-22
已发帖子: 15
积分: 15

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

不错,感谢分享

离线

#13 2020-09-12 23:10:43

1066950103
会员
注册时间: 2017-11-17
已发帖子: 61
积分: 46

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

这个漂亮

离线

#14 2020-09-21 09:33:11

vip888888
会员
注册时间: 2020-07-16
已发帖子: 141
积分: 138

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

用上,无言感谢,只能顶一下。

离线

#15 2020-09-22 18:56:09

shawn.d
会员
注册时间: 2020-09-12
已发帖子: 164
积分: 100

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

厉害厉害!

离线

#16 2020-09-22 20:04:18

f1c100_
会员
注册时间: 2020-09-22
已发帖子: 32
积分: 20.5

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

大佬牛逼

离线

#17 2020-09-23 11:17:01

srovio
会员
注册时间: 2019-10-16
已发帖子: 15
积分: 9.5

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

牛逼, 做个记号

离线

#18 2020-12-16 18:05:04

lovelessing
会员
注册时间: 2020-12-15
已发帖子: 32
积分: 63.5

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

多问一句,lvgl获取控件的中文写到文件里面是不是也需要反向转换的步骤

离线

#19 2020-12-16 20:23:41

armstrong
会员
注册时间: 2019-04-10
已发帖子: 247
积分: 161.5

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

楼主,请问歌曲名左右滚动显示,是lvgl控件内置具备的特性吗?

离线

#20 2020-12-17 09:48:33

vip888888
会员
注册时间: 2020-07-16
已发帖子: 141
积分: 138

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

armstrong 说:

楼主,请问歌曲名左右滚动显示,是lvgl控件内置具备的特性吗?

好像是有这么个功能的我之前看过lvgl的帮助文档label里面有个是这样的。是左右滚还是循环滚应该是可以设置模式的。
void lv_ex_label_text(void)
{
    lv_obj_t * label2 = lv_label_create(lv_scr_act(), NULL);
    lv_label_set_long_mode(label2, LV_LABEL_LONG_SROLL_CIRC);     /*Circular scroll*/
    lv_obj_set_width(label2, 150);
    lv_label_set_text(label2, "It is a circularly scrolling text. ");
    lv_obj_align(label2, NULL, LV_ALIGN_CENTER, 0, 30);
}

离线

#21 2022-12-13 16:23:10

石头
会员
注册时间: 2022-12-13
已发帖子: 1
积分: 1

Re: 研究了1天,终于搞清楚如何在LVGL上显示GBK字串,分享一下让大家少踩坑

程序是GBK转UTF8,有没有另一半,UTF8转GBK的程序?多谢!

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn