OSD好的分析和实现

一, OSD (视频的添加文字和logo的)

添加文字的说明


/*--  文字:  陈  --*/
//%E9%99%88
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=16x16   --*/

/**
0000 0000 0100 0000  // ->0x00,0x40
0111 1000 0100 0000  // ->0x78,0x40
0100 1000 0100 0000  // ->0x48,0x40 
0101 0111 1111 1110  // ->0x57,0xFE
0101 0000 1000 0000  // ->0x50,0x80
0110 0001 0010 0000  // ->0x61,0x20
0101 0001 0010 0000  // ->0x51,0x20
0100 1010 0010 0000  // ->0x4A,0x20
0100 1011 1111 1100  // ->0x4B,0xFC
0100 1000 0010 0000  // ->0x48,0x20
0110 1001 0010 1000  // ->0x69,0x28
0101 0001 0010 0100  // ->0x51,0x24
0100 0010 0010 0010  // ->0x42,0x22
0100 0100 0010 0010  // ->0x44,0x22
0100 0000 1010 0000  // ->0x40,0xA0
0100 0000 0100 0000  // ->0x40,0x40





/////////////////////
                    0000 0000 0@00 0000  
                    0@@@ @000 0@00 0000  
                    0@00 @000 0@00 0000  
                    0@0@ 0@@@ @@@@ @@@0  
                    0@0@ 0000 @000 0000  
                    0@@0 000@ 00@0 0000  
                    0@0@ 000@ 00@0 0000  
                    0@00 @0@0 00@0 0000  
                    0@00 @0@@ @@@@ @@00  
                    0@00 @000 00@0 0000  
                    0@@0 @00@ 00@0 @000  
                    0@0@ 000@ 00@0 0@00  
                    0@00 00@0 00@0 00@0  
                    0@00 0@00 00@0 00@0  
                    0@00 0000 @0@0 0000  
                    0@00 0000 0@00 0000
///////////////////
*/
0x00,0x40,0x78,0x40,0x48,0x40,0x57,0xFE,
0x50,0x80,0x61,0x20,0x51,0x20,0x4A,0x20,
0x4B,0xFC,0x48,0x20,0x69,0x28,0x51,0x24,
0x42,0x22,0x44,0x22,0x40,0xA0,0x40,0x40,

代码的实现



#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

#define FRAME_WIDTH             (352)
#define FRAME_HEIGHT            (288)
#define FRAME_SIZE              (FRAME_WIDTH*FRAME_HEIGHT*3/2)
#define IN_FILENAME             "in.raw"
#define OUT_FILENAME            "out.raw"

const unsigned char table[] = {

/*--  文字:  陈  --*/
//%E9%99%88
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=16x16   --*/

/**
0000 0000 0100 0000  // ->0x00,0x40
0111 1000 0100 0000  // ->0x78,0x40
0100 1000 0100 0000  // ->0x48,0x40 
0101 0111 1111 1110  // ->0x57,0xFE
0101 0000 1000 0000  // ->0x50,0x80
0110 0001 0010 0000  // ->0x61,0x20
0101 0001 0010 0000  // ->0x51,0x20
0100 1010 0010 0000  // ->0x4A,0x20
0100 1011 1111 1100  // ->0x4B,0xFC
0100 1000 0010 0000  // ->0x48,0x20
0110 1001 0010 1000  // ->0x69,0x28
0101 0001 0010 0100  // ->0x51,0x24
0100 0010 0010 0010  // ->0x42,0x22
0100 0100 0010 0010  // ->0x44,0x22
0100 0000 1010 0000  // ->0x40,0xA0
0100 0000 0100 0000  // ->0x40,0x40





/
                    0000 0000 0@00 0000  
                    0@@@ @000 0@00 0000  
                    0@00 @000 0@00 0000  
                    0@0@ 0@@@ @@@@ @@@0  
                    0@0@ 0000 @000 0000  
                    0@@0 000@ 00@0 0000  
                    0@0@ 000@ 00@0 0000  
                    0@00 @0@0 00@0 0000  
                    0@00 @0@@ @@@@ @@00  
                    0@00 @000 00@0 0000  
                    0@@0 @00@ 00@0 @000  
                    0@0@ 000@ 00@0 0@00  
                    0@00 00@0 00@0 00@0  
                    0@00 0@00 00@0 00@0  
                    0@00 0000 @0@0 0000  
                    0@00 0000 0@00 0000
///
*/
0x00,0x40,0x78,0x40,0x48,0x40,0x57,0xFE,
0x50,0x80,0x61,0x20,0x51,0x20,0x4A,0x20,
0x4B,0xFC,0x48,0x20,0x69,0x28,0x51,0x24,
0x42,0x22,0x44,0x22,0x40,0xA0,0x40,0x40,

/*--  文字:  桂  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=16x16   --*/
0x10,0x20,0x10,0x20,0x11,0xFC,0x10,0x20,0xFC,0x20,0x10,0x20,0x33,0xFE,0x38,0x00,
0x54,0x20,0x54,0x20,0x91,0xFC,0x10,0x20,0x10,0x20,0x10,0x20,0x13,0xFE,0x10,0x00,

/*--  文字:  芳  --*/
/*--  楷体_GB231212;  此字体下对应的点阵为:宽x高=16x16   --*/
0x08,0x20,0x08,0x20,0xFF,0xFE,0x08,0x20,0x0A,0x20,0x01,0x00,0xFF,0xFE,0x04,0x00,
0x04,0x00,0x07,0xF0,0x04,0x10,0x08,0x10,0x08,0x10,0x10,0x10,0x20,0xA0,0x40,0x40,

};

/*
* Function:     draw_Font_Func
* Description:  实现在yuv420图片上面画字 
* Input:        char *ptr_frame             一帧视频的首地址
*               const unsigned char font[]  画的字模
*               int startx                  写字的起点坐标x
*               int starty                  写字的起点坐标y
*               int color                   字颜色的选择,具体颜色在程序代码
* Return:       这里会把传进来的一帧视频的地址返回,可以不调用  
*/
char *draw_Font_Func(char *ptr_frame,const unsigned char font[],int startx,int starty,int color)
{

    assert( ptr_frame != NULL );

    int tagY=0,tagU=0,tagV=0;
    char *offsetY=NULL,*offsetU=NULL,*offsetV=NULL;
    unsigned short p16, mask16; // for reading hzk16 dots

    /*yuv 地址的设置 */
    offsetY = ptr_frame;
    offsetU = offsetY + FRAME_WIDTH * FRAME_HEIGHT;
    offsetV = offsetU + FRAME_WIDTH * FRAME_HEIGHT/4;

    switch (color)
    {
        case 0:         // Yellow
            tagY = 226;tagU = 0;tagV = 149;
            break;
        case 1:         // Red
            tagY = 76;tagU = 85;tagV = 255;
            break;
        case 2:         // Green
            tagY = 150;tagU = 44;tagV = 21;
            break;
        case 3:         // Blue
            tagY = 29;tagU = 255;tagV = 107;
            break;
        default:        // White
            tagY = 128;tagU = 128;tagV = 128;
    }  

    int x=0,y=0,i=1,j=0,k=0;
    for(i = 0; i < 3; i++)
    {
    #if 0
        for (j = 0, y = starty; j < 16 && y < FRAME_HEIGHT - 1; j++, y+=2)    // line dots per char
        {
            p16 = *(unsigned short *)(font + j*2 + i*32);/*取字模数据*/
            mask16 = 0x0080;  /* 二进制 1000 0000 */
            for (k = 0, x = startx +i*36; k < 16 && x < FRAME_WIDTH - 1; k++, x+=2)   // dots in a line
            {
                if (p16 & mask16)
                {
                    *(offsetY + y*FRAME_WIDTH + x) = *(offsetY + y*FRAME_WIDTH + x+1) = tagY;
                    *(offsetY + (y+1)*FRAME_WIDTH + x) = *(offsetY + (y+1)*FRAME_WIDTH + x+1) = tagY;   
                    *(offsetU + y * FRAME_WIDTH/4 + x/2) =tagU;
                    *(offsetV + y * FRAME_WIDTH/4 + x/2) = tagV;
                }
                mask16 = mask16 >> 1;  /* 循环移位取数据 */
                if (mask16 == 0)
                    mask16 = 0x8000;
            }
        }
    #else
        //高度的控制
        for (j = 0, y = starty; j < 16 && y < FRAME_HEIGHT - 1; j++, y++) // line dots per char
        {
            p16 = *(unsigned short *)(font + j*2 + i*32);/*取字模数据*/
            mask16 = 0x0080;  /* 二进制 1000 0000 */
            //宽度的控制 
            for (k = 0, x = startx +i*18; k < 16 && x < FRAME_WIDTH - 1; k++, x++) // dots in a line
            {
                //找到要修改的数据的位置
                if (p16 & mask16)  //与操作  相同为1, 不同为0   01000100 & 00000100 = 00000100
                {
                    *(offsetY + y*FRAME_WIDTH + x) = 255;
                //  *(offsetU + y * FRAME_WIDTH/4 + x/2) = 85;
                //  *(offsetV + y * FRAME_WIDTH/4 + x/2) = 255;
                }
                mask16 = mask16 >> 1;  /* 循环移位取数据 ---->*/
                if (mask16 == 0)
                    mask16 = 0x8000;
            }
        }
    #endif
    }

    return (char *)ptr_frame;
}

int main(int argc,char * argv[])
{
    int ret = 0;
    FILE *in_file,*out_file;

    char *frame_buffer = NULL;
    frame_buffer = (char*)malloc(FRAME_SIZE);

    //read frame file 读原来的一帧数据
    in_file = fopen(IN_FILENAME,"r");
    if (in_file == NULL)
    {
        printf("open in file error!\n");
    }

    ret = fread(frame_buffer,FRAME_SIZE,1,in_file);
    if (ret != 1)
    {
        printf("ret = %d\n");
        printf("fread file error!\n");
    }
    fclose(in_file);

    //数据转换
    draw_Font_Func(frame_buffer,table,20,10,1);

    //write frame file 把数据写回
    out_file = fopen(OUT_FILENAME,"w");
    if (out_file == NULL)
    {
        printf("open in file error!\n");
    }

    ret = fwrite(frame_buffer,FRAME_SIZE,1,out_file);
    if (ret != 1)
    {
        printf("ret = %d\n");
        printf("fwrite file error!\n");
    }
    fclose(out_file);
    free(frame_buffer);

    printf("Done!\n");
    return 0;
}

二, 时间的添加



const unsigned char table[] = {

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/

        0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x18,0x18,0x00,0x00,/*"!",1*/

        0x00,0x12,0x36,0x24,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*""",2*/

        0x00,0x00,0x00,0x24,0x24,0x24,0xFE,0x48,0x48,0x48,0xFE,0x48,0x48,0x48,0x00,0x00,/*"#",3*/

        0x00,0x00,0x10,0x38,0x54,0x54,0x50,0x30,0x18,0x14,0x14,0x54,0x54,0x38,0x10,0x10,/*"$",4*/

        0x00,0x00,0x00,0x44,0xA4,0xA8,0xA8,0xA8,0x54,0x1A,0x2A,0x2A,0x2A,0x44,0x00,0x00,/*"%",5*/

        0x00,0x00,0x00,0x30,0x48,0x48,0x48,0x50,0x6E,0xA4,0x94,0x88,0x89,0x76,0x00,0x00,/*"&",6*/

        0x00,0x60,0x60,0x20,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"'",7*/

        0x00,0x02,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x08,0x04,0x02,0x00,/*"(",8*/

        0x00,0x40,0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x00,/*")",9*/

        0x00,0x00,0x00,0x00,0x10,0x10,0xD6,0x38,0x38,0xD6,0x10,0x10,0x00,0x00,0x00,0x00,/*"*",10*/

        0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x00,0x00,0x00,/*"+",11*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x20,0xC0,/*",",12*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"-",13*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,/*".",14*/

        0x00,0x00,0x01,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,/*"/",15*/

        0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00,/*"0",16*/

        0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"1",17*/

        0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x04,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00,/*"2",18*/

        0x00,0x00,0x00,0x3C,0x42,0x42,0x04,0x18,0x04,0x02,0x02,0x42,0x44,0x38,0x00,0x00,/*"3",19*/

        0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x24,0x44,0x44,0x7E,0x04,0x04,0x1E,0x00,0x00,/*"4",20*/

        0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x58,0x64,0x02,0x02,0x42,0x44,0x38,0x00,0x00,/*"5",21*/

        0x00,0x00,0x00,0x1C,0x24,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x24,0x18,0x00,0x00,/*"6",22*/

        0x00,0x00,0x00,0x7E,0x44,0x44,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,/*"7",23*/

        0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00,/*"8",24*/

        0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x26,0x1A,0x02,0x02,0x24,0x38,0x00,0x00,/*"9",25*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,/*":",26*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x20,/*";",27*/

        0x00,0x00,0x00,0x02,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x02,0x00,0x00,/*"<",28*/

        0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,/*"=",29*/

        0x00,0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x02,0x04,0x08,0x10,0x20,0x40,0x00,0x00,/*">",30*/

        0x00,0x00,0x00,0x3C,0x42,0x42,0x62,0x02,0x04,0x08,0x08,0x00,0x18,0x18,0x00,0x00,/*"?",31*/

        0x00,0x00,0x00,0x38,0x44,0x5A,0xAA,0xAA,0xAA,0xAA,0xB4,0x42,0x44,0x38,0x00,0x00,/*"@",32*/

        0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3C,0x44,0x42,0x42,0xE7,0x00,0x00,/*"A",33*/

        0x00,0x00,0x00,0xF8,0x44,0x44,0x44,0x78,0x44,0x42,0x42,0x42,0x44,0xF8,0x00,0x00,/*"B",34*/

        0x00,0x00,0x00,0x3E,0x42,0x42,0x80,0x80,0x80,0x80,0x80,0x42,0x44,0x38,0x00,0x00,/*"C",35*/

        0x00,0x00,0x00,0xF8,0x44,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x44,0xF8,0x00,0x00,/*"D",36*/

        0x00,0x00,0x00,0xFC,0x42,0x48,0x48,0x78,0x48,0x48,0x40,0x42,0x42,0xFC,0x00,0x00,/*"E",37*/

        0x00,0x00,0x00,0xFC,0x42,0x48,0x48,0x78,0x48,0x48,0x40,0x40,0x40,0xE0,0x00,0x00,/*"F",38*/

        0x00,0x00,0x00,0x3C,0x44,0x44,0x80,0x80,0x80,0x8E,0x84,0x44,0x44,0x38,0x00,0x00,/*"G",39*/

        0x00,0x00,0x00,0xE7,0x42,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x42,0xE7,0x00,0x00,/*"H",40*/

        0x00,0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"I",41*/

        0x00,0x00,0x00,0x3E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x88,0xF0,/*"J",42*/

        0x00,0x00,0x00,0xEE,0x44,0x48,0x50,0x70,0x50,0x48,0x48,0x44,0x44,0xEE,0x00,0x00,/*"K",43*/

        0x00,0x00,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0xFE,0x00,0x00,/*"L",44*/

        0x00,0x00,0x00,0xEE,0x6C,0x6C,0x6C,0x6C,0x54,0x54,0x54,0x54,0x54,0xD6,0x00,0x00,/*"M",45*/

        0x00,0x00,0x00,0xC7,0x62,0x62,0x52,0x52,0x4A,0x4A,0x4A,0x46,0x46,0xE2,0x00,0x00,/*"N",46*/

        0x00,0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x44,0x38,0x00,0x00,/*"O",47*/

        0x00,0x00,0x00,0xFC,0x42,0x42,0x42,0x42,0x7C,0x40,0x40,0x40,0x40,0xE0,0x00,0x00,/*"P",48*/

        0x00,0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x82,0xB2,0xCA,0x4C,0x38,0x06,0x00,/*"Q",49*/

        0x00,0x00,0x00,0xFC,0x42,0x42,0x42,0x7C,0x48,0x48,0x44,0x44,0x42,0xE3,0x00,0x00,/*"R",50*/

        0x00,0x00,0x00,0x3E,0x42,0x42,0x40,0x20,0x18,0x04,0x02,0x42,0x42,0x7C,0x00,0x00,/*"S",51*/

        0x00,0x00,0x00,0xFE,0x92,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,/*"T",52*/

        0x00,0x00,0x00,0xE7,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00,/*"U",53*/

        0x00,0x00,0x00,0xE7,0x42,0x42,0x44,0x24,0x24,0x28,0x28,0x18,0x10,0x10,0x00,0x00,/*"V",54*/

        0x00,0x00,0x00,0xD6,0x92,0x92,0x92,0x92,0xAA,0xAA,0x6C,0x44,0x44,0x44,0x00,0x00,/*"W",55*/

        0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x18,0x18,0x18,0x24,0x24,0x42,0xE7,0x00,0x00,/*"X",56*/

        0x00,0x00,0x00,0xEE,0x44,0x44,0x28,0x28,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,/*"Y",57*/

        0x00,0x00,0x00,0x7E,0x84,0x04,0x08,0x08,0x10,0x20,0x20,0x42,0x42,0xFC,0x00,0x00,/*"Z",58*/

        0x00,0x1E,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1E,0x00,/*"[",59*/

        0x00,0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x10,0x08,0x08,0x04,0x04,0x04,0x02,0x02,/*"\",60*/

        0x00,0x78,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x78,0x00,/*"]",61*/

        0x00,0x1C,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"^",62*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,/*"_",63*/

        0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"`",64*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x1E,0x22,0x42,0x42,0x3F,0x00,0x00,/*"a",65*/

        0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x64,0x58,0x00,0x00,/*"b",66*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x22,0x40,0x40,0x40,0x22,0x1C,0x00,0x00,/*"c",67*/

        0x00,0x00,0x00,0x06,0x02,0x02,0x02,0x1E,0x22,0x42,0x42,0x42,0x26,0x1B,0x00,0x00,/*"d",68*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x7E,0x40,0x40,0x42,0x3C,0x00,0x00,/*"e",69*/

        0x00,0x00,0x00,0x0F,0x11,0x10,0x10,0x7E,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"f",70*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x44,0x44,0x38,0x40,0x3C,0x42,0x42,0x3C,/*"g",71*/

        0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x42,0xE7,0x00,0x00,/*"h",72*/

        0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"i",73*/

        0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x1C,0x04,0x04,0x04,0x04,0x04,0x04,0x44,0x78,/*"j",74*/

        0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x4E,0x48,0x50,0x68,0x48,0x44,0xEE,0x00,0x00,/*"k",75*/

        0x00,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"l",76*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x49,0x49,0x49,0x49,0x49,0xED,0x00,0x00,/*"m",77*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x62,0x42,0x42,0x42,0x42,0xE7,0x00,0x00,/*"n",78*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00,/*"o",79*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD8,0x64,0x42,0x42,0x42,0x44,0x78,0x40,0xE0,/*"p",80*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x22,0x42,0x42,0x42,0x22,0x1E,0x02,0x07,/*"q",81*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x32,0x20,0x20,0x20,0x20,0xF8,0x00,0x00,/*"r",82*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x42,0x40,0x3C,0x02,0x42,0x7C,0x00,0x00,/*"s",83*/

        0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x10,0x10,0x10,0x0C,0x00,0x00,/*"t",84*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0x42,0x42,0x42,0x42,0x46,0x3B,0x00,0x00,/*"u",85*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x28,0x10,0x10,0x00,0x00,/*"v",86*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD7,0x92,0x92,0xAA,0xAA,0x44,0x44,0x00,0x00,/*"w",87*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x24,0x18,0x18,0x18,0x24,0x76,0x00,0x00,/*"x",88*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x28,0x18,0x10,0x10,0xE0,/*"y",89*/

        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x44,0x08,0x10,0x10,0x22,0x7E,0x00,0x00,/*"z",90*/

        0x00,0x03,0x04,0x04,0x04,0x04,0x04,0x08,0x04,0x04,0x04,0x04,0x04,0x04,0x03,0x00,/*"{
                                                                                    ",91*/

        0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,/*"|",92*/

        0x00,0x60,0x10,0x10,0x10,0x10,0x10,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x60,0x00,
};

//ptr_frame为YUV420格式字符数组,str为叠加的字符串,startx、starty为要叠加的位置,length为叠加字符的长度
char* draw_Font_Func(unsigned char *ptr_frameY, unsigned char *ptr_frameU,unsigned char *ptr_frameV,const char *str,int startx,int starty,int color,int length, int wid, int heig)
{

    int tagY=0,tagU=0,tagV=0;
    unsigned char *offsetY=NULL,*offsetU=NULL,*offsetV=NULL;
    unsigned short p16, mask16; // for reading hzk16 dots

    //yuv 地址的设置
    offsetY = ptr_frameY;
    offsetU = ptr_frameU;// + WIDTH * HEIGHT;
    offsetV = ptr_frameV;// + WIDTH * HEIGHT/4;
    const  char *p = str;

    switch (color)
    {

        case 0:         // Yellow
            tagY = 226;tagU = 0;tagV = 149;
            break;
        case 1:         // Red
            tagY = 76;tagU = 85;tagV = 255;
            break;
        case 2:         // Green
            tagY = 150;tagU = 44;tagV = 21;
            break;
        case 3:         // Blue
            tagY = 29;tagU = 255;tagV = 107;
            break;
        default:        // White
            tagY = 128;tagU = 128;tagV = 128;

    }

    int x=0,y=0,i=1,j=0,k=0;
    for(i = 0; i < length ;i++)
    {
        for (j = 0, y = starty; j < 16 && y < heig - 1; j++, y+=2)
        {

            p16 = (unsigned short )table[(*p-32)*16+j];
            mask16 = 0x0080;  // 二进制 1000 0000
            //for (k = 0, x = startx +i*32; k < 16 && x < WIDTH - 1; k++, x+=2)   // dots in a line
            for (k = 0, x = startx +i*16; k < 8 && x < wid - 1; k++, x+=2)
            {

                if (p16 & mask16)
                {

                    *(offsetY + y*wid + x) = *(offsetY + y*wid + x+1) = tagY;
                    *(offsetY + (y+1)*wid + x) = *(offsetY + (y+1)*wid + x+1) = tagY;
                    *(offsetU + y * wid/4 + x/2) =tagU;
                    *(offsetV + y * wid/4 + x/2) = tagV;
                }
                mask16 = mask16 >> 1;  //循环移位取数据
                if (mask16 == 0)
                    mask16 = 0x8000;
            }

        }
        p++;
    }
    return "";

}

调用说明

 draw_Font_Func(y, u, v, "2018-03-26 17:12:12", 10, 10, 3, 19, this->mWidth , this->mHeight);

三, 添加logo的分析

/*************************************************************************
    > File Name: 三级指针.c
    > Author: songli
    > QQ: 2734030745
    > Mail: 15850774503@163.com
    > CSDN: http://blog.csdn.net/Poisx
    > Github: https://github.com/chensongpoixs
    > Created Time: 2017/8/27 星期日
 ************************************************************************/
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>

using namespace std;  //使用   标准的命名空间



const int  NV21OR21 = 1;
const int YUV420SP = 2;


/**
参数的含义:yuvType -------------------------- yuv类型,目前只支持NV12和NV21
tarYuv  -------------------------- 存储裁剪结果的内存
srcYuv  -------------------------- 原始YUV数据,通过fread获取
startW,startH -------------------------- 开始裁剪的坐标位置
cutW,cutH -------------------------- 裁剪过后的分辨率
srcW,srcH -------------------------- 原始YUV数据的分辨率
*/
void cutYuv(int yuvType, unsigned char *tarYuv, 
    unsigned char *srcYuv, int startW, int startH, 
    int cutW, int cutH, int srcW, int srcH) {

    int i, j = 0, k = 0;
    //分配一段内存,用于存储裁剪后的Y分量
    unsigned char *tmpY = (unsigned char *)malloc(cutW * cutH);
    //分配一段内存,用于存储裁剪后的UV分量
    unsigned char *tmpUV = (unsigned char *)malloc(cutW*cutH / 2);
    /*switch (yuvType) {
    case NV21OR21:*/
        //Y数据的拷贝
        for (i = startH; i<cutH + startH; i++) {
            // 逐行拷贝Y分量,共拷贝cutW*cutH
            memcpy(tmpY + j*cutW, srcYuv + startW + i*srcW, cutW);
            j++;
        }

        //UV
        for (i = startH / 2; i<(cutH + startH) / 2; i++) {
            //逐行拷贝UV分量,共拷贝cutW*cutH/2
            memcpy(tmpUV + k*cutW, srcYuv + startW + srcW*srcH + i*srcW, cutW);
            k++;
        }
        //将拷贝好的Y,UV分量拷贝到目标内存中
        memcpy(tarYuv, tmpY, cutW*cutH);
        memcpy(tarYuv + cutW*cutH, tmpUV, cutW*cutH / 2);
        free(tmpY);
        free(tmpUV);
    //  break;
    //case YUV420SP:
    //  //Not FInished
    //  break;
    //}
}




/**
参数的含义:yuvType   -------------------------- yuv类型,目前只支持NV12和NV21
startX,startY   -------------------------- 需要添加水印的位置
waterMarkData -------------------------- 水印YUV数据,可以通过读取水印文件获取
waterMarkW,waterMarkH -------------------------- 水印数据的分辨率
yuvData -------------------------- 源YUV图像数据
yuvW,yuvH -------------------------- 源YUV的分
*/
void yuvAddWaterMark(int yuvType, 
    int startX, int startY, 
    unsigned char *waterMarkData, int waterMarkW, int waterMarkH, 
    unsigned char *yuvData, int yuvW, int yuvH) {
    int i = 0;
    int j = 0;
    int k = 0;
    /*switch (yuvType) {
    case NV21OR21:*/
        //Y
        for (i = startY; i<waterMarkH + startY; i++) {
            memcpy(yuvData + startX + i*yuvW, waterMarkData + j*waterMarkW, waterMarkW);
            j++;
        }
        //UV
        for (i = startY / 2; i<(waterMarkH + startY) / 2; i++) {
            memcpy(yuvData + startX + yuvW*yuvH + i*yuvW, waterMarkData + waterMarkW*waterMarkH + k*waterMarkW, waterMarkW);
            k++;
        }

#if 1
        FILE *outPutFp = fopen("Final.yuv", "w+");
        fwrite(yuvData, 1, yuvW*yuvH * 3 / 2, outPutFp);
        fclose(outPutFp);
#endif

        /*break;*/
    //case YUV420SP:
    //  //Not FInished
    //  break;
    //default:
    //  //Not FInished
    //  break;
    //}
}



/**
只要不拷贝0x10和0x80就好
*/
int fCutWaterMark(unsigned char *waterMarkSrc, 
    unsigned char *srcYuv, 
    int waterMarkW, int waterMarkH) {
    int i;

    //unsigned char tmpData[waterMarkW * waterMarkH * 3 / 2];
    //unsigned char tmpWaterMark[waterMarkW * waterMarkH * 3 / 2];
    unsigned char tmpData[238 * 96 * 3 / 2];
    unsigned char tmpWaterMark[238 * 96 * 3 / 2];
    memcpy(tmpData, srcYuv, waterMarkW * waterMarkH * 3 / 2);
    memcpy(tmpWaterMark, waterMarkSrc, waterMarkW * waterMarkH * 3 / 2);
    for (i = 0; i<waterMarkW * waterMarkH * 3 / 2; i++) {
        if (tmpWaterMark[i] != 0x10 && tmpWaterMark[i] != 0x80 && tmpWaterMark[i] != 0xeb) {
            tmpData[i] = tmpWaterMark[i];
            // printf("0x%X\n", tmpData[i]);
        }
    }
    memcpy(waterMarkSrc, tmpData, waterMarkW*waterMarkH * 3 / 2);
#if 1
    FILE *tarFp = fopen("afterCutWaterMark.yuv", "w+");
    fwrite(waterMarkSrc, 1, waterMarkW*waterMarkH * 3 / 2, tarFp);
    fclose(tarFp);
#endif 
    return 0;
}






int main(void)
{

    FILE *src = fopen("tz_1080_1438.yuv", "rb+");
    FILE *des = fopen("238_96.yuv", "rb+");

    unsigned char *srcyuv = (unsigned char *)malloc(1080 * 1438 * 1.5);
    unsigned char *desyuv = (unsigned char *)malloc(238 * 96 * 1.5);
    fread(srcyuv, 1, 1080 * 1438 * 1.5, src);
    fread(desyuv, 1, 238 * 96 * 1.5, des);

    /**
    参数的含义:yuvType -------------------------- yuv类型,目前只支持NV12和NV21
    tarYuv  -------------------------- 存储裁剪结果的内存
    srcYuv  -------------------------- 原始YUV数据,通过fread获取
    startW,startH -------------------------- 开始裁剪的坐标位置
    cutW,cutH -------------------------- 裁剪过后的分辨率
    srcW,srcH -------------------------- 原始YUV数据的分辨率
    */
    ///unsigned char *tmpY = (unsigned char *)malloc(cutW * cutH);
    unsigned char *tarYuv = (unsigned char *)malloc(238 * 96 *1.5);
    cutYuv(1, tarYuv,
        srcyuv, 3, 3,
        238, 96, 1080 , 1438);
    fCutWaterMark(desyuv, tarYuv, 238, 96);
    yuvAddWaterMark(1, 3, 3, desyuv,
        238, 96, srcyuv, 1080 , 1438 );



    free(src);
    free(des);


    system("pause");
    return EXIT_SUCCESS;
}

这里写图片描述

这里我下赋上带加logo的图片 还有bug

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值