DM36x IPNC OSD显示中文 --- 基本数据准备篇

经过上一篇的叙述,基本原理搞清楚后,便需要对我们在OSD上显示中文作数据准备,
首先是需要将gb2312关键区(也就是实际有文字存在的区)中的汉字转换为图片,在实际的转换中,并不像上一篇中GB2312编码转换为UNICODE描述一样,
使用libiconv库中的iconv函数将94x94的gb2312编码表直接传递给iconv函数会转换失败(错误提示不完整的多字节字符或宽字符).为了简化这其中的转换难度,目前使用的是查表的方法将GB2312编码转换为UNICODE编码,
这样就要求先准备好GB2312 UNICODE对照表,这个表网上有各种形式的,但是通过我花了很长时间查找也没有找到合适自己需求的,主要是网上的GB2312区位码不全,都会丢掉某些区中的某些编码,这样会有个问题,
就是我们转换后的数据需要记录我们中间丢失了哪些编码,对应的位置等等.会造成后续程序执行效率降低和设计难度加大.这里我是直接将94x94个GB2312编码都转换为对应的unicode编码,保存在一个数组中(很占篇幅,这里不贴实际数据了),通过查找下标的方式查找对应的UNICODE编码.
将对应的GB2312编码转换为UNICODE编码后,接下来就是使用Freetype2将该UNICODE码提取出对应的字符映像,并转换为位图,保存在磁盘上了,下面是其中的核心程序:
//linux下保存24位bmp图像,数据结构FileHead、Infohead见上一篇

 1 int save_bmp24(char * filename,int width,int height,unsigned char *data)
 2 {
 3     FileHead bmp_head;
 4     Infohead bmp_info;
 5     int size = width*height*3;
 6     FILE *fp = fopen(filename,"wb");
 7     if(!fp)
 8     {
 9         perror("open file error");
10         return -1;
11     }
12
13     bmp_head.bfType=0x4d42;
14     bmp_head.bfSize=size+sizeof(FileHead)+sizeof(Infohead);//24+head+info no quad
15     bmp_head.bfReserved1=bmp_head.bfReserved2=0;
16     bmp_head.bfOffBits=bmp_head.bfSize-size;
17
18     bmp_info.biSize=40;
19     bmp_info.biWidth=width;
20     bmp_info.biHeight=-height;//如果为正数,转换出来的图片还需要进行垂直翻转
21     bmp_info.biPlanes=1;
22     bmp_info.biBitCount = 24;
23     bmp_info.biCompress=0;
24     bmp_info.biSizeImage=size;
25     bmp_info.biXPelsPerMeter=0;
26     bmp_info.biYPelsPerMeter=0;
27     bmp_info.biClrUsed=0;
28     bmp_info.biClrImportant=0;
29
30     fwrite(&bmp_head,1,sizeof(FileHead),fp);
31     fwrite(&bmp_info,1,sizeof(Infohead),fp);
32     fwrite(data,1,size,fp);
33     fclose(fp);
34     return 0;
35 }

//转换函数,这里是一个区转换为一个图片

  1 int convert(const char * font_file,int font_width,int font_height)
  2 {
  3     FT_Library library = NULL;
  4     FT_Face face = NULL;
  5     int error;
  6     int char_index;
  7     int char_code;
  8
  9     unsigned char * bmpdata = NULL,*pdata;//保存一个字的图片数据
 10     int isVert = 0;//是否垂直布局,中文为垂直布局
 11     FT_Bitmap *ft_bmp;
 12
 13     unsigned short  unicode;//用于存储unicode
 14     int index=0;
 15     int area,location;
 16     char testfilename[100];
 17
 18     unsigned char *image = NULL, *pimage;//一个区转换为一张图片
 19     int temp;
 20
 21     if(font_width <= 0 && font_height <= 0)
 22     {
 23         printf("invalidate font size.\n");
 24         return -1;
 25     }
 26     if(font_width <= 0)
 27         font_width = font_height;
 28     if(font_height <= 0)
 29         font_height = font_width;
 30     if(font_width % 2)//4字节对齐,这里先保证宽度为4pixel对齐
 31     {
 32         printf("invalidate font size.\n");
 33         return -1;
 34     }
 35     setlocale(LC_ALL,"zh_CN.UTF-8");
 36
 37     do
 38     {
 39         //下面开始初始化FT2库
 40         error = FT_Init_FreeType(&library);
 41         if (error)
 42         {
 43             printf("can not init free type library!\n");
 44             break;
 45         }
 46
 47         error = FT_New_Face(library, font_file, 0, &face);
 48         if (error)
 49         {
 50             printf("create new face falied!\n");
 51             break;
 52         }
 53         isVert = FT_HAS_VERTICAL(face);
 54         error = FT_Set_Pixel_Sizes(face, font_width, font_height);//设置字体大小
 55         if (error)
 56         {
 57             printf("set font size error!\n");
 58             break;
 59         }
 60         bmpdata = malloc(font_width * font_height * 3);
 61         if(!bmpdata)
 62         {
 63             printf("outof memory.\n");
 64             break;
 65         }
 66         image = malloc(94 * font_width * font_height * 3);//这里要求font_size必须为偶数
 67         if(!image)
 68         {
 69             printf("outof memory.\n");
 70             break;
 71         }
 72
 73 #if 0
 74         //打印字体相关信息
 75         printf("file has %d faces\n", face->num_faces);
 76         printf("%s  italic or oblique,%s bold\n", face->style_flags & FT_STYLE_FLAG_ITALIC ?"support":"not support",face->style_flags & FT_STYLE_FLAG_BOLD ?"support":"not support");
 77         printf("file family name %s\n", face->family_name);
 78         printf("file style name %s\n", face->style_name);
 79         printf("face index %d\n", face->face_index);
 80         printf("number of char %d\n", face->num_glyphs);
 81         printf("number of fixed bitmap %d\n", face->num_fixed_sizes);
 82         printf("Char size %d\n", face->size);
 83         printf("has %d fixed sizes\n",face->num_fixed_sizes);
 84         for(i=0;i<face->num_fixed_sizes;i++)
 85         {
 86             printf("supported size %d:width=%d,heigh=%d\n",i+1,face->available_sizes[i].width,face->available_sizes[i].height);
 87         }
 88 #endif
 89         error = FT_Select_Charmap(face,FT_ENCODING_UNICODE);//这里使用UNICODE映射表,便于使用UNICODE码(char code)来获取char index
 90         if(error)
 91         {
 92             printf("select char map error.\n");
 93             break;
 94         }
 95         //printf("code %x\n",face ->charmap ->encoding);
 96         switch(face ->charmap ->encoding)
 97         {
 98             case FT_ENCODING_MS_GB2312:    printf("USE GB2312 CODE\n");break;
 99             case FT_ENCODING_MS_BIG5:    printf("USE BIG5 CODE\n");break;
100             case FT_ENCODING_UNICODE:    printf("USE UNICODE CODE\n");break;
101             default:
102                 printf("UNKNOWN CODE\n");
103                 goto done;
104                 break;
105         }
106
107         //实际有字体的区码为(0-8) (15-86)区(区号从0开始 ) = 9 + 72 = 81个区
108         for(area = 0;area < 87;area ++)//1- 87区
109         {
110             if( (area >8 && area < 15)/* 8 - 15区跳过*/
111                 ||(area > 86 && area < 94)/* 87 - 94 区跳过*/
112             )
113             {
114                 continue;
115             }
116             memset(image,0,94 * font_width * font_height * 3);
117             pimage = image;
118             for(location = 0;location < 94;location++)//1 - 94位
119             {
120                 index = area * 94 + location;
121                 if(Gb2312ToUnicode(gb2312_table[index],&unicode) < 0)
122                 {
123                     printf("get unicode code error.gb2312 code 0x%04X\n",gb2312_table[index]);
124                     continue;
125                 }
126                 char_code = unicode;
127                 if(!char_code)
128                 {
129                     printf("\ninvalidate char code.\n");
130                     continue;
131                 }
132                 char_index = FT_Get_Char_Index(face,char_code);
133                 error = FT_Load_Glyph(face, char_index,  FT_LOAD_DEFAULT | FT_LOAD_MONOCHROME);
134                 if (error)
135                 {
136                     printf("\nload char error!\n");
137                     goto done;
138                 }
139                 if (face->glyph->format != FT_GLYPH_FORMAT_BITMAP)
140                 {
141                     error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO);
142                     if (error)
143                     {
144                         printf("\nrender char failed!\n");
145                         goto done;
146                     }
147                 }
148
149                 /*
150                 单色位图图像数据的表示方法:
151                 在单色位图图像中,只有两种颜色,黑色或白色,每一个像素只需要一个比特就能够完成表示,为了清楚比特0或1具体表示哪一种颜色,可以通过查询调色板。
152                 在单色位图图像中,调色板只包含两种颜色,每一种颜色用R G B 0 四个字节表示 (在实际的字节流中,顺序是 B G R 0)
153                 所以,位图图像数据中的0 代表调色板中 第一种颜色的颜色值, 1 代表调色板中 第二种颜色的颜色值。
154                 一行单色位图数据的存储格式规定:
155                 每一扫描行的字节数必需是4的整倍数,当不够4的整数倍时,需要加0补齐
156                 以 720 × 450 的单色位图图像为例
157                 水平扫描行的长度为720,则需要720比特来表示一个扫描行,即需要 720/8=90字节来表示,但是 90不是 4 的整数倍,因此需要用0补齐,直至为4的整数倍,即需要额外的2个填充字节。
158                 最终,长度为720的水平扫描行使用了 92 个字节来表示。
159                 NOTE:非8位位图可用函数FT_Bitmap_Convert进行转换
160                 */
161                 //转换为4字节对齐
162                 ft_bmp = &face->glyph->bitmap;
163 #if 0
164                 //dump位图信息
165                 printf("bit_map_left %d bit_map_top %d\n", face->glyph->bitmap_left,face->glyph->bitmap_top);
166                 printf("int rows:%d\n",ft_bmp ->rows);
167                 printf("int width:%d\n",ft_bmp ->width);
168                 printf("int pitch:%d\n",ft_bmp ->pitch);
169                 printf("short num_grays:%d\n",ft_bmp ->num_grays);
170                 printf("char pixel_mode:%d\n",ft_bmp ->pixel_mode);
171                 if(isVert)
172                 {
173                     printf("VERT:(w:%ld h:%ld)(bearingX:%ld bearingY:%ld Advance:%ld)\n",face->glyph->metrics.width/64,face->glyph->metrics.height/64,
174                         face->glyph->metrics.vertBearingX/64,face->glyph->metrics.vertBearingY/64,face->glyph->metrics.horiAdvance/64);
175                 }
176                 else
177                 {
178                     printf("HORI:(w:%ld h:%ld)(bearingX:%ld bearingY:%ld Advance:%ld)\n",face->glyph->metrics.width/64,face->glyph->metrics.height/64,
179                         face->glyph->metrics.horiBearingX/64,face->glyph->metrics.horiBearingY/64,face->glyph->metrics.vertAdvance/64);
180                 }
181                 printf("xMin=%ld, yMin=%ld, xMax=%ld, yMax=%ld\n",face ->bbox.xMin,face ->bbox.yMin,face ->bbox.xMax,face ->bbox.yMax);
182 #endif
183
184                 switch(ft_bmp ->pixel_mode)
185                 {
186                     case FT_PIXEL_MODE_MONO://单色位图
187                         {
188                             //将数据转换到24位
189                             int topblank     = 0;//字型顶部距离位图顶部空行数目
190                             int leftblank     = 0;//字型左边距离位图左边空列数目
191                             int rightblank     = 0;//字型右边距离位图右边空列数目
192                             int pitch     = 0;//每个扫描行占用几个字节
193                             int width    = ft_bmp ->width;//实际字型宽度
194                             int height    = ft_bmp ->rows; //实际字型高度
195                             unsigned char * ft_bmp_buff = ft_bmp ->buffer;
196                             int i,j,k;
197                             if(isVert)
198                             {
199                                 topblank     = face->glyph->metrics.vertBearingY/64;
200                                 leftblank     = font_width/2 + face->glyph->metrics.vertBearingX/64;
201                             }
202                             else
203                             {
204                                 topblank    = font_height * 2 /3 - face->glyph->metrics.horiBearingY/64;
205                                 leftblank     = face->glyph->metrics.horiBearingX/64;
206                             }
207                             if(topblank < 0)topblank     = 0;
208                             if(leftblank < 0)leftblank     = 0;
209                             rightblank = font_width - width - leftblank;
210                             if(rightblank < 0)rightblank    = 0;
211                             pitch =  ft_bmp ->width / 8;
212                             if(pitch% ft_bmp ->pitch)
213                                 pitch = pitch + (ft_bmp ->pitch - pitch %ft_bmp ->pitch);
214                             //printf("PITCH=%d\n",pitch);
215
216                             //转换1bit位图数据到24bit位图数据
217                             printf("begin convert.area %d ----> %d\r",area,location);
218                             memset(bmpdata,0,font_width * font_height * 3);
219                             pdata = bmpdata;
220                             pdata += topblank *font_width * 3;//跳过上边距
221                             for(i=0;i<height;i++)
222                             {
223                                 pdata += leftblank * 3;
224                                 k = 7;
225                                 for(j=0;j<width;j++)
226                                 {
227                                     if(ft_bmp_buff[j/8] & (1 << k) )
228                                     {
229                                         //pdata[0] = 255;//蓝
230                                         pdata[1] = 255;//绿
231                                         pdata[2] = 255;//红
232                                     }
233                                     k--;
234                                     if(k<0)k=7;
235                                     pdata += 3;
236                                 }
237                                 ft_bmp_buff += pitch;
238                                 pdata += rightblank * 3;
239                             }
240                             /*if(!(font_width %4))
241                             {
242                                 sprintf(testfilename,"./testbmp/%d_%d.bmp",area,location );
243                                 printf("\nsave bmp file [%s]\n",testfilename);
244                                 if(save_bmp24(testfilename,font_width ,font_height,bmpdata))
245                                 {
246                                     printf("save bmp file [%s] error.\n",testfilename);
247                                 }
248                             }*/
249
250                         }
251                         break;
252                     default:
253                         printf("位图为非单色图片.\n");
254                         goto done;
255                         break;
256                 }//switch
257                 pdata = bmpdata;
258                 pimage = image + location * font_width * 3;
259                 for(temp=0;temp<font_height;temp++)
260                 {
261                     memcpy(pimage,pdata,font_width * 3);
262                     pdata += font_width * 3;
263                     pimage += 94 * font_width *3;
264                 }
265 #ifndef _WIN32
266                 usleep(10);
267 #else
268                 Sleep(10);
269 #endif
270             }//for( 1 - 94 位 )
271             //保存图片
272             sprintf(testfilename,"./testbmp/area%d_%dx%d.bmp",area,font_width,font_height);
273             //printf("\nsave bmp file [%s]\n",testfilename);
274             if(save_bmp24(testfilename,94 * font_width,font_height,image))
275             {
276                 printf("save bmp file [%s] error.\n",testfilename);
277             }
278         }//for( 1 - 94 区)
279         printf("\nConvert Done.\n");
280
281     }while (0);
282 done:
283 #if 0    //出现莫名其妙的错误,注释了
284     fprintf(stderr,"begin cleanup.\n");
285     if(bmpdata)
286     {
287         free(bmpdata);
288         bmpdata = NULL;
289     }
290     if(image)
291     {
292         free(image);
293         image = NULL;
294     }
295     if(face)
296     {
297         FT_Done_Face(face);
298         face = NULL;
299     }
300     if(library)
301     {
302         FT_Done_FreeType(library);
303         library = NULL;
304     }
305 #endif
306     return 0;
307 }

这里上传几个程序转换的图片:

14x16:

16x18:


20x24:

28x32:

将编码转换为图片后,需要将bmp24图片数据转换为yuv420p数据,利用libswscale库进行转换的核心代码已经在上一篇贴了,这里不再重贴.
下面是转换后的结果,当然也可以直接将数据保存为一个二进制文件,而不是一个C源程序文件

 1 /*********************Y***************************/
 2 unsigned char data_Y[]={
 3      0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10
 4     ,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10
 5     ,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10
 6     ,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10
 7     ......
 8     ,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10
 9     ,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10
10     ,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10
11     ,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10
12 };
13 //37224 bytes
14 /**************end of Y***************************/
15
16 /********************UV***************************/
17 unsigned char data_UV[]={
18      0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
19     ,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
20     ,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
21     ,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
22     ......
23     ,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
24     ,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
25     ,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x12,0x92,0x80,0x80,0x80,0x80
26     ,0x80,0x80,0x80,0x80
27 };
28 //18612 bytes
29 /*************end of UV***************************/

http://blog.csdn.net/sloan6/article/details/9231373

时间: 2024-10-09 23:22:57

DM36x IPNC OSD显示中文 --- 基本数据准备篇的相关文章

DM36x IPNC OSD显示中文 --- 基础知识篇

为了简单起见,只显示GB2312(简体中文)字符一.GB2312汉字编码1.区位码在国标GB2312—80中规定,所有的国标汉字及符号分配在一个94行.94列的方阵中,方阵的每一行称为一个“区”,编号为01区到94区,每一列称为一个“位”,编号为01位到94位,方阵中的每一个汉字和符号所在的区号和位号组合在一起形成的四个阿拉伯数字就是它们的“区位码”.区位码的前两位是它的区号,后两位是它的位号.用区位码就可以唯一地确定一个汉字或符号,反过来说,任何一个汉字或符号也都对应着一个唯一的区位码.汉字“

DM36x IPNC OSD显示中文 --- 实战篇

通过数据准备篇,将数据准备好后,其实剩下的工作已经很简单了,通过以下几个步骤即可把一个中文显示在OSD画面上:1. 使用SWOSD_setBmpchangeWinXYPrm函数设置好OSD显示坐标位置;2. 设置SWOSD_Hndl句柄中SWOSD_BmpWinPrm类型成员数组中对应的窗口的width,height,lineOffset对应的值,width是OSD窗口宽度,如果yuv数据来自的是32x32的bmp图片,则width=n*32,其中n为字符个数,height为OSD窗口高度,li

C#基础系列:开发自己的窗体设计器(PropertyGrid显示中文属性名)

既然是一个窗体设计器,那就应该能够设置控件的属性,设置属性最好的当然是PropertyGrid了,我们仅仅需要使用一个PropertyGrid.SelectedObject = Control就可以搞定,让PropertyGrid显示Control的所有属性.可是这里显示的属性名是英文的.对于我们开发人员来说这无可厚非,我们也乐于接受.并且让PropertyGrid显示中文属性名,这对于我们开发人员的使用来说显得多此一举.可是,对于我这种类型的一个应用工具,英文属性名对于很多客户来说可能就很难懂

让UIWebView弹出键盘上的按钮显示中文

UIWebView是一个很常用的视图,一般用来加载网页,比如百度: 点击文本框输入框后,会弹出一个带有toolbar的键盘,toolbar中有3个辅助按钮 有了这3个按钮,是方便很多,但默认是英文的,有时我们想把按钮文字变为中文 其实办法很简单,只需要让你的应用程序支持中文本地化,意思是在项目中新建一个中文的本地化文件夹zh-Hans.lproj 如果还不太了解什么叫本地化,可以看看我的这篇文章<应用程序本地化> 下面简单演示下操作步骤: 1.添加中文本地化支持 2.选择要支持本地化的文件,至

matplotlib 显示中文

# --*-- coding: utf-8 --*-- from matplotlib.font_manager import FontProperties import matplotlib.pyplot as plt font = FontProperties(fname=r"/usr/share/fonts/win/msyh.ttf", size=14) fig = plt.figure(figsize=(6, 6)) x = [1, 2, 3, 4, 5, 6, 7, 8] y

基于Windows环境下cmd/编译器无法输入中文,显示中文乱码解决方案

基于Windows环境下cmd/编译器无法输入中文,显示中文乱码解决方案 两个月前做C++课设的时候,电脑编译器编译结果出现了中文乱码,寻求了百度和大神们,都没有解决这个问题,百度上一堆解释是对编译器进行设置之类的,结果没有一个有效果,暑假学习了用Dos来开发Java程序,输入cmd命令中dir(directory)进行查询操作时,显示了一堆中文乱码,原本是想重装系统的,因为电脑里面重要东西有点多,所以自己花了一段时间捣鼓了一下电脑,终于解决了如上两个问题,现在心里很开心,附上如下两幅图: cm

解决IE9支持CSS中文字体经验篇

如何让CSS中使用中文字体后仍然在IE9浏览器显示兼容.(音乐放松椅) 一.CSS中文字体IE9兼容出现问题CSS中使用中文字体后Line-height样式在IE9浏览器垂直上下居中样式失效. 二.解决IE9兼容中文字体将CSS中使用中文字体的中文字转化为Unicode编码然后替代.最终设置字体效果将不受转换编码而影响同时也兼容了Line-height垂直居中样式,同时IE9即可兼容CSS中使用常用中文字体.(音乐放松椅) 常见字体转换:黑体:\9ED1\4F53宋体:\5B8B\4F53微软雅

Zabbix显示中文或图片为乱码--解决方法

Web UI 修改为中文: 1.进行zabbix系统后选择:Administration,在子菜单中选择:Users: 2.在最右列的:User groups更改为Users; 3.选择:Admin 点击 4.在下面的:Language中选择:Chinese(zh_CN) 5.点击:Save 6.刷新网页即可 如果还是不行可以尝试以下方法: # sed -i '/zh_CN/ s/false/true/' /var/www/html/zabbix/include/locales.inc.php 

ubuntu下使用matplotlib绘图无法显示中文label

原因是字体导致的.大家的做法基本都是搞一个windows上的字体文件(simhei.ttf, 点我fq下载)然后刷新一下缓存文件. 只不过百度搜到第一篇CSDN的博客,写的很不靠谱(不是所有的CSDN都不靠谱,但是相当多的都不靠谱.) 靠谱的做法: 首先要明白,你用的是哪个matplotlib,是apt安装的python-matplotlib还是pip装的matplotlib,是python2的还是python3的?(以及,也许你是anaconda装的?) 找到你用的matplotlib包所使用