• 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     #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!
    ");
    145     }
    146 
    147     ret = fread(frame_buffer,FRAME_SIZE,1,in_file);
    148     if (ret != 1)
    149     {
    150         printf("ret = %d
    ");
    151         printf("fread file error!
    ");
    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!
    ");
    163     }
    164     
    165     ret = fwrite(frame_buffer,FRAME_SIZE,1,out_file);
    166     if (ret != 1)
    167     {
    168         printf("ret = %d
    ");
    169         printf("fwrite file error!
    ");
    170     }
    171     fclose(out_file);
    172     free(frame_buffer);
    173   
    174     printf("Done!
    ");
    175     return 0;
    176 }
  • 相关阅读:
    文本属性和字体属性
    BZOJ 2724: [Violet 6]蒲公英
    BZOJ4010: [HNOI2015]菜肴制作
    BZOJ 2160: 拉拉队排练
    HDU-5157Harry and magic string
    HDU-5421Victor and String
    BZOJ2565: 最长双回文串(回文树)
    BZOJ3676: [Apio2014]回文串(回文树)
    BZOJ 3195: [Jxoi2012]奇怪的道路(状压dp)
    BZOJ1758: [Wc2010]重建计划(01分数规划+点分治+单调队列)
  • 原文地址:https://www.cnblogs.com/eustoma/p/6661839.html
Copyright © 2020-2023  润新知