UTF-8与GBK字符之间的转换
一、本文提纲
在嵌入式产品中,难免会遇到由服务器或者APP端推送的消息内容,而大多数推送消息内容的字符编码都为UTF-8,底层硬件需要将推送的消息送到LCD或者OLED等屏幕上进行显示,此时就涉及到一个编码转换的内容,因为硬件不能直接将UTF-8编码的字符进行显示,必须经过算法将UTF-8编码对照Unicode编码转换为GBK汉字编码之后才能显示,而本文介绍从外部FLASH中读取Unicode编码和GBK字符编码,将UTF-8字符转换为GBK字符。
二、UTF-8转换为GBK字符的原理
1.UTF-8转换为Unicode编码
UTF-8编码不能直接转换为GBK汉字编码,中间需要先转换为Unicode编码,在由Unicode编码转换为GBK汉字编码
2.Unicode编码转换为GBK汉字编码
Unicode汉字编码与GBK汉字编码的对照关系为,两个Unicode编码对应一个汉字,并且在Unicode编码中,汉字编码的起始位置是0x4e00,也就是说将UTF-8汉字编码转换为Unicode编码时需要偏移0x4e00去读取数据。
三、UTF-8转换为GBK字符的C代码实现过程
1.从flash读取Unicode编码
unsigned short mb_uni2gb_table[]={0};
uint16_t Read_flash_unicode(uint16_t* unicode,uint32_t ReadAddr,uint16_t num_len)
{uint8_t buff[10];//缓冲区 ReadAddr=ReadAddr+Offset_addr;//为存储在flash 中的偏移地址SPI_Flash_Read_2(buff,ReadAddr,num_len);unicode[0]=(buff[1]<<8)|buff[0];return 1;
}
2.UTF-8转换为Unicode编码
int SwitchToGbk(const unsigned char* pszBufIn, int nBufInLen, unsigned char* pszBufOut, int* pnBufOutLen)
{int i = 0;int j = 0;int nLen;unsigned short unicode;unsigned short gbk;for(; i < nBufInLen; i++, j++){if((pszBufIn[i] & 0x80) == 0x00) // 1位{nLen = 1;pszBufOut[j]= pszBufIn[i];}else if((pszBufIn[i] & 0xE0) == 0xC0)// 2位{nLen = 2;unicode = (pszBufIn[i] & 0x1F << 6) | (pszBufIn[i+1]& 0x3F);}else if ((pszBufIn[i] & 0xF0) == 0xE0) // 3位 {if (i+ 2 >= nBufInLen) return -1; unicode = (((int)(pszBufIn[i] & 0x0F)) << 12) | (((int)(pszBufIn[i+1] & 0x3F)) << 6) | (pszBufIn[i+2] & 0x3F); //从flash读取Unicode编码Read_flash_unicode(mb_uni2gb_table,(unicode-0x4e00)*2,2);gbk = *mb_uni2gb_table;pszBufOut[j]= gbk/256;pszBufOut[j+1] = gbk%256;j++;i+=2;}else{return -1;}}*pnBufOutLen = j;return 0;
}
3.Unicode编码转换为GBK汉字编码
void Get_HzMat(unsigned char *code,unsigned char *mat)
{ unsigned char qh,ql;unsigned char i; unsigned long foffset; uint8_t size = 16;uint8_t csize=(size/8+((size%8)?1:0))*(size);//得到字体一个字符对应点阵集所占的字节数 qh=*code;ql=*(++code);if(qh<0x81||ql<0x40||ql==0xff||qh==0xff)//非 常用汉字{ for(i=0;i<csize;i++)*mat++=0x00;//填充满格return; //结束访问} if(ql<0x7f)ql-=0x40;//注意!else ql-=0x41;qh-=0x81; foffset=((unsigned long)190*qh+ql)*csize; //得到字库中的字节偏移量 SPI_Flash_Read_2(mat,foffset+Offset_addr,csize);//Offset_addr为GBK存储在flash中的起始偏移地址
}
四、ST7735s显示屏应用案例
1.lcd显示单个汉字的应用案例
/***************************************************************************************
** 函数名称 **:void Show_Font(uint16_t x,uint16_t y,uint8_t *font,uint16_t fc)
** 函数功能 **:lcd显示单个汉字
** 输入参数 **:uint16_t x,uint16_t y,uint8_t *font(汉字内容),uint16_t fc(汉字颜色)
** 输出参数 **:无
** 返 回 值 **:无
****************************************************************************************/
void Show_Font(uint16_t x,uint16_t y,uint8_t *font,uint16_t fc)
{uint8_t size = 16;//固定显示16号字体uint8_t temp,t,t1;uint16_t y0=y;uint8_t dzk[72]; uint8_t csize=(size/8+((size%8)?1:0))*(size);//得到字体一个字符对应点阵集所占的字节数 if(size!=12&&size!=16&&size!=24)return; //不支持的sizeGet_HzMat(font,dzk); //得到相应大小的点阵数据 for(t=0;t<csize;t++){ temp=dzk[t]; //得到点阵数据 for(t1=0;t1<8;t1++){ if(temp&0x80)Gui_DrawPoint(x,y,fc);//lcd基础描点函数temp<<=1;y++;if((y-y0)==size){y=y0;x++;break;}} }
}
2.在指定区域内自动换行显示多个汉字
void Show_Str(uint16_t x,uint16_t y,uint16_t width,uint16_t height,uint8_t*str,uint16_t fc)
{ uint8_t size = 16; uint16_t x0=x;uint16_t y0=y; uint8_t bHz=0; //字符或者中文 GPIO_Pin_Clear(U32BIT(LCD_CS));while(*str!=0)//数据未结束{ if(!bHz){if(*str>0x80)bHz=1;//中文 else //字符{ if(x>(x0+width-size/2))//换行{ y+=size;x=x0; } if(y>(y0+height-size))break;//越界返回 if(*str==13)//换行符号{ y+=size;x=x0;str++; } else LCD_ShowChar(x,y,*str,fc);//有效部分写入 str++; x+=size/2; //字符,为全字的一半 }}else//中文 { bHz=0;//有汉字库 if(x>(x0+width-size))//换行{ y+=size;x=x0; }if(y>(y0+height-size))break;//越界返回 Show_Font(x,y,str,fc); //显示这个汉字,空心显示 str+=2; x+=size;//下一个汉字偏移 } } GPIO_Pin_Set(U32BIT(LCD_CS));
}
UTF-8与GBK字符之间的转换相关推荐
- JavaScript 进行数值与对应的 ASCII 字符之间的转换【fromCharCode、fromCodePoint、charCodeAt、codePointAt】
引言: 今天遇到一个需求,需要动态创建一个 JS 对象数组,对象中的 key 值并不都是一样的(准确说是一个有序的字母),具体如下: var options = [{"A":&qu ...
- UTF8与GBK字符编码转换
utf8与gbk字符之间的转换主要用到两个方法 WideCharToMultiByte:http://baike.baidu.com/view/2083430.htm?fr=aladdin Multi ...
- utf-8 GB2312 GBK三者之间的区别
各个国家和地区所制定的不同 ANSI 编码标准中,都只规定了各自语言所需的"字符".比如:汉字标准(GB2312)中没有规定韩国语字符怎样存储.这些 ANSI 编码标准所规定的内容 ...
- BSTR、char* 和 CString 之间的转换 (转)
BSTR.char* 和 CString 之间的转换 (1) char*转换成CString 若将char*转换成CString,除了直接赋值外,还可使用CString::Format进行.例如: c ...
- android utf-8 转 gbk编码,【字符编码系列】GBK,UTF-8,UTF-16之间的转换
写在前面的话 本文属于 字符编码系列文章之一,更多请前往 字符编码系列. 大纲 不同编码转换的理论基础 UTF-16转UTF-8 UTF-16转GBK UTF-16和UTF-8之间的转换 UTF-16 ...
- 汉字编码(【Unicode】 【UTF-8】 【Unicode与UTF-8之间的转换】 【汉字 Unicode 编码范围】【中文标点Unicode码】【GBK编码】【批量获取汉字UNICODE码】)
参考博客: Unicode与UTF-8互转(C语言实现):http://blog.csdn.net/tge7618291/article/details/7599902 汉字 Unicode 编码范围 ...
- UTF8与GBK字符编码之间的相互转换
UTF8与GBK字符编码之间的相互转换 C++ UTF8编码转换 CChineseCode 一 预备知识 1,字符:字符是抽象的最小文本单位.它没有固定的形状(可能是一个字形),而且没有值.&qu ...
- GBK和UTF8之间的转换 C语言
来自 :http://www.diybl.com/course/3_program/c++/cppsl/2008320/105871.html GBK和UTF8之间的转换可以使用MultiByteTo ...
- java ucs2转utf8_Unicode,UTF8,GB2312,UCS2,GBK之间的转换
Unicode,UTF8,GB2312,UCS2,GBK之间的转换 平时用到的几种编码格式转换.平时用的不是很多.但是在做短信协议的时候,就经常遇到了.这段时间做短信平台接口,总结了几个,也不是很全. ...
- Java 字节流、字符流和转换流之间的关系
1. 字节流.字符流和转换流之间的关系 (1)字节流:读取字节到内存或将字节写入硬盘文件中. (2)字符流:将字节转换为字符(读入)或将字符转换为字节(写出). (3)转换流:将字节按照指定的编码格式 ...
最新文章
- python使用什么作为转义字符-详解用Python处理HTML转义字符的5种方式
- PHP如何验证以太坊签名
- 本地提交到yarn_Flink on Yarn三部曲之三:提交Flink任务
- 实验2-4-6 求幂之和 (C语言)
- 单线程多线程_理解线程,就会由单线程向多线程进军
- 编译问题处理:undefined symbol: OPENSSL_init_crypto
- opencv_判断两张图片是否相同
- 跟踪调试易语言静态编译支持库的方法
- 微商加人方法,感动你我的加人故事
- 医院体检PEIS系统
- linux视频补帧,如何用 60 帧播放 24 帧的视频?
- 微信小程序中map地图中取消地点图标文字(干净地图)
- android关闭背光
- c/c++使用数据库sqlite3
- vs2017打开项目后项目是空的
- 征信报告产生“不良记录”的主要原因?
- 台北房价窥北京未来:调控阻止不了高房价
- SpringBoot学生信息管理系统_毕业设计(附源码)
- OSCS-软件供应链安全威胁与业界解决方案
- 深大uooc大学生心理健康章节答案第十章