嵌入式中的软字幕的实现(ARGB1555) freetype的应用
很久没有写笔记了,整理一下资料和大家分享一下
函数的实现功能为字幕(汉字/字母/数字)转换为ARGB1555来数据图像信息
这个功能的实现只要有两点:
1、字幕转换为unicode码
2、unicode码转换为空间信息(相对于取字模)
其他都是一些简单的逻辑的实现了,非常的简单;下面的列子是转换为ARGB1555,(海思字幕只支持这个)同样可以转换rgb888,rgb565,BMP等
后面喜欢怎么玩就怎么玩了;
//转换数字字母汉字为unicode码
setlocale(LC_ALL,"");
mbstowcs(draw_subtitle_info.subtitle_num,draw_subtitle_info.subtitle_buf,strlen(draw_subtitle_info.subtitle_buf));
最后输出的数据可以用7yuv这个软件来查看。
- /*
- 注:这个文件的存储格式必须是utf—8 / utf-8 无 ROM 格式编码
- */
- #include "stdio.h"
- #include "string.h"
- #include "stdlib.h"
- #include "locale.h"
- #include <ft2build.h>
- #include <freetype/freetype.h>
- #include <freetype/fttrigon.h>
- #include <freetype/ftstroke.h>
- #define REGION_FONT_WIDTH 720
- #define REGION_FONT_HEIGHT 480
- #define REGION_FONT_FSIZE (REGION_FONT_WIDTH * REGION_FONT_HEIGHT * 2)
- /*像素点结构体,这里是ARGB1555的结构*/
- typedef struct {
- unsigned int a:1;
- unsigned int r:5;
- unsigned int g:5;
- unsigned int b:5;
- } colour_argb_t;
- /*绘字幕结构体*/
- typedef struct {
- char *region_ptr;
- char subtitle_buf[128];
- wchar_t subtitle_num[128];
- unsigned int startx;
- unsigned int starty;
- unsigned int font_size;
- } draw_subtitle_t;
- char *UNILangPath = "simfang.ttf";
- colour_argb_t colour_argb_front,colour_argb_back;
- draw_subtitle_t draw_subtitle_info;
- int region_draw_subtitle_func(void)
- {
- unsigned int psize = draw_subtitle_info.font_size;
- int row, pixel;
- int i,j,k;
- int debug_num = 0;
- //转换数字字母汉字为unicode码
- setlocale(LC_ALL,"");
- mbstowcs(draw_subtitle_info.subtitle_num,draw_subtitle_info.subtitle_buf,strlen(draw_subtitle_info.subtitle_buf));
- //printf("subtitle_buf = *%s*\n",draw_subtitle_info.subtitle_buf);
- //for(i=0;i<strlen(draw_subtitle_info.subtitle_buf);i++)
- // printf("%x\n",draw_subtitle_info.subtitle_num);
- FT_Library library;
- FT_Face face;
- FT_UInt glyph_index;
- if(FT_Init_FreeType(&library))
- return 11;
- if(FT_New_Face(library, UNILangPath,0, &face))
- return 12;
- //FT_Set_Pixel_Sizes(face, 40,60); //直接设置高宽
- if(FT_Set_Pixel_Sizes(face, psize,0))
- return 13;
- k = 0;
- while(1)
- {
- //查看转换的unicode码转换完了没有,完了就退出循环
- if(draw_subtitle_info.subtitle_num[k] <= 0)
- {
- //printf("%x\n",draw_subtitle_info.subtitle_num[k]);
- break;
- }
- //这里把转码出来的unicode码设置一下
- glyph_index = FT_Get_Char_Index(face, draw_subtitle_info.subtitle_num[k++]);
- if(glyph_index == 0)
- {
- return 2;
- }
- if(FT_Load_Glyph(face,glyph_index,FT_LOAD_DEFAULT))
- {
- return 3;
- }
- if(FT_Render_Glyph(face->glyph,FT_RENDER_MODE_MONO))
- {
- return 4;
- }
- /*
- printf("bitmap_left=%d\n"
- "bitmap_top=%d\n"
- "bitmap.rows=%d\n"
- "bitmap.width=%d\n"
- "bitmap.pitch=%d\n"
- "bitmap.pixel_mode=%d\n",
- face->glyph->bitmap_left,
- face->glyph->bitmap_top,
- face->glyph->bitmap.rows,
- face->glyph->bitmap.width,
- face->glyph->bitmap.pitch,
- face->glyph->bitmap.pixel_mode);
- printf("\n\n");
- */
- /*字母在绘制过程中没有办法自动对其,在这里做了一个参考来经行字母对齐*/
- if( face->glyph->bitmap_top < (psize+10) )
- debug_num = psize + 10 - face->glyph->bitmap_top;
- else
- debug_num = 0;
- /*扫描绘字幕,这样处理的效率是非常的高的,只直接绘制字幕*/
- for(row = 0,j = draw_subtitle_info.starty + debug_num; row < face->glyph->bitmap.rows; ++row,++j)
- {
- for(pixel = 0,i = draw_subtitle_info.startx; pixel < face->glyph->bitmap.width; ++pixel,++i)
- {
- if(face->glyph->bitmap.buffer[row * face->glyph->bitmap.pitch +pixel/8] & (0xC0 >> (pixel % 8)))
- memcpy(draw_subtitle_info.region_ptr+i*2+j*REGION_FONT_WIDTH*2,&colour_argb_front,2);
- else
- memcpy(draw_subtitle_info.region_ptr+i*2+j*REGION_FONT_WIDTH*2,&colour_argb_back,2);
- }
- }
- //如果这里是一个空格,就把坐标跳过去一个字符单位
- if (face->glyph->bitmap.width == 0)
- draw_subtitle_info.startx += psize;
- else
- draw_subtitle_info.startx += face->glyph->bitmap.width + 2;
- }
- return 0;
- }
- int main()
- {
- /*如果是rgb888 数据,只需要取高位数据就可以了 5位*/
- /*字体颜色*/
- colour_argb_front.a = 0x00;
- colour_argb_front.r = 0x1F;
- colour_argb_front.g = 0x1F;
- colour_argb_front.b = 0x1F;
- /*字体背景颜色*/
- colour_argb_back.a = 0x00;
- colour_argb_back.r = 0x1F;
- colour_argb_back.g = 0x00;
- colour_argb_back.b = 0x00;
- char subtitle_buffer[128] = "2014beijing 创新改变世界北京";
- draw_subtitle_info.font_size = 30; //字号的设置
- memcpy(draw_subtitle_info.subtitle_buf,subtitle_buffer,strlen(subtitle_buffer));
- draw_subtitle_info.region_ptr = (char *)malloc(REGION_FONT_FSIZE);
- memset(draw_subtitle_info.region_ptr,0,REGION_FONT_FSIZE);
- draw_subtitle_info.startx = 0;
- draw_subtitle_info.starty = 0;
- /*把字幕画到内存里面,里面会有一个局部扫描的过程,
- 只绘制了字体的背景,其他背景没有经行绘制,可以先绘制整个背景后再来画字*/
- region_draw_subtitle_func();
- FILE * fp = fopen("720x576_white.raw","wb");
- fwrite(draw_subtitle_info.region_ptr,REGION_FONT_FSIZE,1,fp);
- fclose(fp);
- free(draw_subtitle_info.region_ptr);
- draw_subtitle_info.region_ptr = NULL;
- return 0;
- }
|