首页 > 代码库 > YUV420视频上面添加字幕

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:            xubbwd@gmail.com 10 */ 11  12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <assert.h> 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     #else109         for (j = 0, y = starty; j < 16 && y < FRAME_HEIGHT - 1; j++, y++) // line dots per char110         {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 line114             {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     #endif127     }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视频上面添加字幕