YUV420视频上面添加字幕

1、source_code
main.c中实现了函数draw_Font_Func(),这个函数可以直接移植到C程序中使用。
zimo.h里面放的是字模转码后的数据。

2、data_yuv
测试用的yuv420数据(352*288) CIF格式,测试前后的数据。

3、zimo_gr.zip
取字幕的软件

  1 /*
  2 * Copyright(C), 2008-2013, Ubuntu Inc.
  3 * File name:        main.c
  4 * Author:           xubinbin 徐彬彬 (Beijing China)
  5 * Version:          1.0
  6 * Date:             2013.06.09
  7 * Description:      
  8 * Function List:    char *draw_Font_Func(char *ptr_frame,const unsigned char font[],int startx,int starty,int color)
  9 * Email:            [email protected]
 10 */
 11 
 12 #include 
 13 #include 
 14 #include 
 15 #include <string.h>
 16 
 17 #include "zimo.h"
 18         
 19 #define FRAME_WIDTH             (352)
 20 #define FRAME_HEIGHT            (288)
 21 #define FRAME_SIZE              (FRAME_WIDTH*FRAME_HEIGHT*3/2)
 22 #define IN_FILENAME             "in.raw"
 23 #define OUT_FILENAME            "out.raw"
 24   
 25 const unsigned char table[] = {
 26 
 27 /*--  文字:  陈  --*/
 28 /*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=16x16   --*/
 29 0x00,0x40,0x78,0x40,0x48,0x40,0x57,0xFE,0x50,0x80,0x61,0x20,0x51,0x20,0x4A,0x20,
 30 0x4B,0xFC,0x48,0x20,0x69,0x28,0x51,0x24,0x42,0x22,0x44,0x22,0x40,0xA0,0x40,0x40,
 31   
 32 /*--  文字:  桂  --*/
 33 /*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=16x16   --*/
 34 0x10,0x20,0x10,0x20,0x11,0xFC,0x10,0x20,0xFC,0x20,0x10,0x20,0x33,0xFE,0x38,0x00,
 35 0x54,0x20,0x54,0x20,0x91,0xFC,0x10,0x20,0x10,0x20,0x10,0x20,0x13,0xFE,0x10,0x00,
 36   
 37 /*--  文字:  芳  --*/
 38 /*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=16x16   --*/
 39 0x08,0x20,0x08,0x20,0xFF,0xFE,0x08,0x20,0x0A,0x20,0x01,0x00,0xFF,0xFE,0x04,0x00,
 40 0x04,0x00,0x07,0xF0,0x04,0x10,0x08,0x10,0x08,0x10,0x10,0x10,0x20,0xA0,0x40,0x40,
 41 
 42 };
 43   
 44 /*
 45 * Function:     draw_Font_Func
 46 * Description:  实现在yuv420图片上面画字 
 47 * Input:        char *ptr_frame             一帧视频的首地址
 48 *               const unsigned char font[]  画的字模
 49 *               int startx                  写字的起点坐标x
 50 *               int starty                  写字的起点坐标y
 51 *               int color                   字颜色的选择,具体颜色在程序代码
 52 * Return:       这里会把传进来的一帧视频的地址返回,可以不调用  
 53 */
 54 char *draw_Font_Func(char *ptr_frame,const unsigned char font[],int startx,int starty,int color)
 55 {
 56   
 57     assert( ptr_frame != NULL );
 58   
 59     int tagY=0,tagU=0,tagV=0;
 60     char *offsetY=NULL,*offsetU=NULL,*offsetV=NULL;
 61     unsigned short p16, mask16; // for reading hzk16 dots
 62       
 63     /*yuv 地址的设置 */
 64     offsetY = ptr_frame;
 65     offsetU = offsetY + FRAME_WIDTH * FRAME_HEIGHT;
 66     offsetV = offsetU + FRAME_WIDTH * FRAME_HEIGHT/4;
 67       
 68     switch (color)
 69     {
 70         case 0:         // Yellow
 71             tagY = 226;tagU = 0;tagV = 149;
 72             break;
 73         case 1:         // Red
 74             tagY = 76;tagU = 85;tagV = 255;
 75             break;
 76         case 2:         // Green
 77             tagY = 150;tagU = 44;tagV = 21;
 78             break;
 79         case 3:         // Blue
 80             tagY = 29;tagU = 255;tagV = 107;
 81             break;
 82         default:        // White
 83             tagY = 128;tagU = 128;tagV = 128;
 84     }  
 85       
 86     int x=0,y=0,i=1,j=0,k=0;
 87     for(i = 0; i < 3; i++)
 88     {
 89     #if 0
 90         for (j = 0, y = starty; j < 16 && y < FRAME_HEIGHT - 1; j++, y+=2)    // line dots per char
 91         {
 92             p16 = *(unsigned short *)(font + j*2 + i*32);/*取字模数据*/
 93             mask16 = 0x0080;  /* 二进制 1000 0000 */
 94             for (k = 0, x = startx +i*36; k < 16 && x < FRAME_WIDTH - 1; k++, x+=2)   // dots in a line
 95             {
 96                 if (p16 & mask16)
 97                 {
 98                     *(offsetY + y*FRAME_WIDTH + x) = *(offsetY + y*FRAME_WIDTH + x+1) = tagY;
 99                     *(offsetY + (y+1)*FRAME_WIDTH + x) = *(offsetY + (y+1)*FRAME_WIDTH + x+1) = tagY;   
100                     *(offsetU + y * FRAME_WIDTH/4 + x/2) =tagU;
101                     *(offsetV + y * FRAME_WIDTH/4 + x/2) = tagV;
102                 }
103                 mask16 = mask16 >> 1;  /* 循环移位取数据 */
104                 if (mask16 == 0)
105                     mask16 = 0x8000;
106             }
107         }
108     #else
109         for (j = 0, y = starty; j < 16 && y < FRAME_HEIGHT - 1; j++, y++) // line dots per char
110         {
111             p16 = *(unsigned short *)(font + j*2 + i*32);/*取字模数据*/
112             mask16 = 0x0080;  /* 二进制 1000 0000 */
113             for (k = 0, x = startx +i*18; k < 16 && x < FRAME_WIDTH - 1; k++, x++) // dots in a line
114             {
115                 if (p16 & mask16)
116                 {
117                     *(offsetY + y*FRAME_WIDTH + x) = 255;
118                 //  *(offsetU + y * FRAME_WIDTH/4 + x/2) = 85;
119                 //  *(offsetV + y * FRAME_WIDTH/4 + x/2) = 255;
120                 }
121                 mask16 = mask16 >> 1;  /* 循环移位取数据 */
122                 if (mask16 == 0)
123                     mask16 = 0x8000;
124             }
125         }
126     #endif
127     }
128   
129     return (char *)ptr_frame;
130 }
131   
132 int main(int argc,char * argv[])
133 {
134     int ret = 0;
135     FILE *in_file,*out_file;
136         
137     char *frame_buffer = NULL;
138     frame_buffer = (char*)malloc(FRAME_SIZE);
139         
140     //read frame file 读原来的一帧数据
141     in_file = fopen(IN_FILENAME,"r");
142     if (in_file == NULL)
143     {
144         printf("open in file error!\n");
145     }
146 
147     ret = fread(frame_buffer,FRAME_SIZE,1,in_file);
148     if (ret != 1)
149     {
150         printf("ret = %d\n");
151         printf("fread file error!\n");
152     }
153     fclose(in_file);
154   
155     //数据转换
156     draw_Font_Func(frame_buffer,table,20,10,1);
157         
158     //write frame file 把数据写回
159     out_file = fopen(OUT_FILENAME,"w");
160     if (out_file == NULL)
161     {
162         printf("open in file error!\n");
163     }
164     
165     ret = fwrite(frame_buffer,FRAME_SIZE,1,out_file);
166     if (ret != 1)
167     {
168         printf("ret = %d\n");
169         printf("fwrite file error!\n");
170     }
171     fclose(out_file);
172     free(frame_buffer);
173   
174     printf("Done!\n");
175     return 0;
176 }

 

你可能感兴趣的:(YUV420视频上面添加字幕)