嵌入式中的软字幕的实现(ARGB1555) freetype的应用

2019-07-15 15:13发布

嵌入式中的软字幕的实现(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* ",draw_subtitle_info.subtitle_buf);
  •         //for(i=0;i<strlen(draw_subtitle_info.subtitle_buf);i++)
  •         //        printf("%x ",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 ",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 "
  •                 "bitmap_top=%d "
  •                 "bitmap.rows=%d "
  •                 "bitmap.width=%d "
  •                 "bitmap.pitch=%d "
  •                 "bitmap.pixel_mode=%d ",
  •                 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(" ");
  • */
  •                 /*字母在绘制过程中没有办法自动对其,在这里做了一个参考来经行字母对齐*/
  •                 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位*/
  •         /*字体颜 {MOD}*/
  •     colour_argb_front.a = 0x00;
  •     colour_argb_front.r = 0x1F;
  •     colour_argb_front.g = 0x1F;
  •     colour_argb_front.b = 0x1F;
  •         /*字体背景颜 {MOD}*/
  •     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;
  • }





友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。