在视频界面上写汉字往往是在GUI中写,但要想文字作为视频中的数据存储下来则要在帧buff中叠加汉字点阵,关于汉字点阵无非是区位码的计算问题,汉字占两个字节,英文一个字节。本文件调用了szHZK16和szASC16字库分别作为汉字和英文字库矩阵,例如:“经度”的“经”这个字在字库矩阵的位置用
"p16 = (unsigned short )Chinese[2738*32+2*j];p17 = (unsigned short )Chinese[2738*32+2*j+1];
"确定,这里的2738表示“经”位于字库中以32个元素为一组的第2739组。offsetY表示灰度值(0--255)
/**********************************
sw_osd_yuv.c
**************************************/
#include
#include "sw_osd_yuv.h"
#include "CharSet.h"
#include
/***********************************************************
ÔÐÍ: char* draw_font(FONT_DRAW_INFO_S * fontDrawInfo)
¹ŠÄÜ: ÊÓƵÉÏÈíµþŒÓ×ÖÄ»
args: ptr_frame: YUV420žñÊœ×Ö·ûÊý×飬
str: µþŒÓµÄ×Ö·ûŽ®£¬
startx¡¢starty: µþŒÓµÄλÖã¬
length: µþŒÓ×Ö·ûµÄ³€¶È
char* µþŒÓ×Ö·ûºóµÄÊÓƵ
return:
*********************************************************/
int draw_font(FONT_DRAW_INFO_S * fontDrawInfo)
{
int tagY=0, tagU=0, tagV=0;
int startx=0, starty=0;
int width=0, heigh=0;
int color=0, length=0;
unsigned char *ptr_frame=NULL;
unsigned char *offsetY=NULL,*offsetU=NULL,*offsetV=NULL;
unsigned short p16, p17, mask16; // for reading hzk16 dots
const char *p = fontDrawInfo->str;
static int cnt=0;
/* -------------------info-----------------------------------------------------*/
POSIT_S positInfo;
if(cnt++%25==0 ){
GetDetectData(&positInfo);
printf("lon:%s* lat:%s* az:%s* pitch:%s* dist:%s* %s\n",
(char *)(positInfo.lon), (char *)(positInfo.lat),
(char *)(positInfo.pitch), (char *)(positInfo.az),
(char *)(positInfo.dist),__FILE__);
}
const char *p1 = positInfo.lon; // longitude: 123°44'50"E or 123.44.50 E
const char *p2 = positInfo.lat;
const char *p3 = positInfo.az;
const char *p4 = positInfo.pitch;
const char *p5 = positInfo.dist;
unsigned char *Chinese = (unsigned char *)szHZK16;
unsigned char *English = (unsigned char *)szASC16;
if( NULL == fontDrawInfo ||
NULL == fontDrawInfo->buf ||
NULL == fontDrawInfo->str ){
printf("args invalid: fontDrawInfo:%d .buf:%d .str:%d.\n",
(int)fontDrawInfo,
(int)fontDrawInfo->buf,
(int)fontDrawInfo->str);
return -1;
}else if( 0==fontDrawInfo->len){
printf("None string to need draw.\n");
return 0;
}else{
startx=fontDrawInfo->x, starty=fontDrawInfo->y;
width=fontDrawInfo->w, heigh =fontDrawInfo->h;
color=fontDrawInfo->color, length=fontDrawInfo->len;
ptr_frame=fontDrawInfo->buf;
//p = fontDrawInfo->str;
}
//yuv µØÖ·µÄÉèÖÃ
//assert( ptr_frame != NULL );
offsetY = ptr_frame;
offsetU = offsetY + width * heigh;
offsetV = offsetU + width * heigh/4;
//RGB_Y=0, RGB_R=1,RGB_G=2,RGB_B=3,RGB_w=4,
switch (color)
{
case 0: // Yellow
tagY = 226;tagU = 0;tagV = 149;
break;
case 1: // Red
tagY = 0;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;
case 4: // White
tagY = 128;tagU = 128;tagV = 128;
default: // black
tagY = 0;tagU = 0;tagV = 0;
}
int x=0,y=0,i=1,j=0,k=0;
/* --------------------------英文:经度值------------------------------------------------*/
for(i = 0; i < 12; i++)
{
// line dots per char
for (j = 0, y = starty; j < 16 && y < starty+16; j++, y+=1)
{
p16 = (unsigned short )English[(*p1)*16+j];
mask16 = 0x0080; // ¶þœøÖÆ 1000 0000
// dots in a line
for (k = 0, x = startx + 32 +i*8; k < 8 && x < startx + 32 +i*8+8; k++, x+=1)
{
if (p16 & mask16)
{
*(offsetY + y*width + x) = tagY;
}
else{
//*(offsetY + y*width + x) = 1; //black
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;// half-trans
}
mask16 = mask16 >> 1; //Ñ»·ÒÆλȡÊýŸÝ
if (mask16 == 0)
mask16 = 0x8000;
}
}
p1++;
}
/* --------------------------英文:纬度值------------------------------------------------*/
for(i = 0; i < 12; i++)
{
// line dots per char
for (j = 0, y = starty; j < 16 && y < starty+16; j++, y+=1)
{
p16 = (unsigned short )English[(*p2)*16+j];
mask16 = 0x0080; // ¶þœøÖÆ 1000 0000
// dots in a line
for (k = 0, x = startx + 32 +128 +i*8; k < 8 && x < startx + 32 +128 +i*8+8; k++, x+=1)
{
if (p16 & mask16)
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
mask16 = mask16 >> 1; //Ñ»·ÒÆλȡÊýŸÝ
if (mask16 == 0)
mask16 = 0x8000;
}
}
p2++;
}
/* --------------------------英文:倾角值------------------------------------------------*/
for(i = 0; i < 12; i++)
{
// line dots per char
for (j = 0, y = starty; j < 16 && y < starty+16; j++, y+=1)
{
p16 = (unsigned short )English[(*p3)*16+j];
mask16 = 0x0080; // ¶þœøÖÆ 1000 0000
// dots in a line
for (k = 0, x = startx + 32 +256 +i*8; k < 8 && x < startx + 32 +256 +i*8+8; k++, x+=1)
{
if (p16 & mask16)
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
mask16 = mask16 >> 1; //Ñ»·ÒÆλȡÊýŸÝ
if (mask16 == 0)
mask16 = 0x8000;
}
}
p3++;
}
/* --------------------------英文:方位值------------------------------------------------*/
for(i = 0; i < 12; i++)
{
// line dots per char
for (j = 0, y = starty; j < 16 && y < starty+16; j++, y+=1)
{
p16 = (unsigned short )English[(*p4)*16+j];
mask16 = 0x0080; // ¶þœøÖÆ 1000 0000
// dots in a line
for (k = 0, x = startx + 32 +384 +i*8; k < 8 && x < startx + 32 +384 +i*8+8; k++, x+=1)
{
if (p16 & mask16)
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
mask16 = mask16 >> 1; //Ñ»·ÒÆλȡÊýŸÝ
if (mask16 == 0)
mask16 = 0x8000;
}
}
p4++;
}
/* --------------------------英文:距离值------------------------------------------------*/
for(i = 0; i < 8; i++)
{
// line dots per char
for (j = 0, y = starty; j < 16 && y < starty+16; j++, y+=1)
{
p16 = (unsigned short )English[(*p5)*16+j];
mask16 = 0x0080; // ¶þœøÖÆ 1000 0000
// dots in a line
for (k = 0, x = startx + 32 +512 +i*8; k < 8 && x < startx + 32 +512 +i*8+8; k++, x+=1)
{
if (p16 & mask16)
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
mask16 = mask16 >> 1; //Ñ»·ÒÆλȡÊýŸÝ
if (mask16 == 0)
mask16 = 0x8000;
}
}
p5++;
}
/* --------------------------汉字:经度-------------------------------------------------*/
// line dots per char
for (j = 0, y = starty; j < 16 && y < starty+16; j++, y+=1)//heigh - 1
{
//p16 = (unsigned short )Chinese[(*p)*16+j];
p16 = (unsigned short )Chinese[2738*32+2*j];
p17 = (unsigned short )Chinese[2738*32+2*j+1];
mask16 = 0x0080; // ¶þœøÖÆ 1000 0000
// dots in a line
for (k = 0, x = startx ; k < 8 && x < startx +8; k++, x+=1)//width - 1
{
if (p16 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
for (k = 0, x = startx +8; k < 8 && x < startx +16; k++, x+=1)//width - 1
{
if (p17 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
}
for (j = 0, y = starty; j < 16 && y < starty+16; j++, y+=1)//heigh - 1
{
//p16 = (unsigned short )table[(*p)*16+j];
p16 = (unsigned short )Chinese[2013*32+2*j];
p17 = (unsigned short )Chinese[2013*32+2*j+1];
mask16 = 0x0080; // ¶þœøÖÆ 1000 0000
// dots in a line
for (k = 0, x = startx + 16; k < 8 && x < startx + 16+8; k++, x+=1)//width - 1
{
if (p16 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
for (k = 0, x = startx + 16+8; k < 8 && x < startx + 16+16; k++, x+=1)//width - 1
{
if (p17 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY; //= *(offsetY + y*width + x+1)
// *(offsetY + (y+1)*width + x) = *(offsetY + (y+1)*width + x+1) = tagY;
// *(offsetU + y * width/4 + x/2) =tagU;
// *(offsetV + y * width/4 + x/2) = tagV;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
}
/* --------------------------汉字:纬度-------------------------------------------------*/
// line dots per char
for (j = 0, y = starty; j < 16 && y < starty+16; j++, y+=1)//heigh - 1
{
//p16 = (unsigned short )table[(*p)*16+j];
p16 = (unsigned short )Chinese[4248*32+2*j];
p17 = (unsigned short )Chinese[4248*32+2*j+1];
mask16 = 0x0080; // ¶þœøÖÆ 1000 0000
// dots in a line
for (k = 0, x = startx + 128; k < 8 && x < startx +8 + 128; k++, x+=1)//width - 1
{
if (p16 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
for (k = 0, x = startx +8 + 128; k < 8 && x < startx +16 + 128; k++, x+=1)//width - 1
{
if (p17 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
}
for (j = 0, y = starty; j < 16 && y < starty+16; j++, y+=1)//heigh - 1
{
//p16 = (unsigned short )table[(*p)*16+j];
p16 = (unsigned short )Chinese[2013*32+2*j];
p17 = (unsigned short )Chinese[2013*32+2*j+1];
mask16 = 0x0080; // ¶þœøÖÆ 1000 0000
// dots in a line
for (k = 0, x = startx + 16 + 128; k < 8 && x < startx + 16+8 + 128; k++, x+=1)//width - 1
{
if (p16 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
for (k = 0, x = startx + 16+8 + 128; k < 8 && x < startx + 16+16 + 128; k++, x+=1)//width - 1
{
if (p17 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
}
/* --------------------------汉字:倾角-------------------------------------------------*/
// line dots per char
for (j = 0, y = starty; j < 16 && y < starty+16; j++, y+=1)//heigh - 1
{
//p16 = (unsigned short )table[(*p)*16+j];
p16 = (unsigned short )Chinese[3638*32+2*j];
p17 = (unsigned short )Chinese[3638*32+2*j+1];
mask16 = 0x0080; // ¶þœøÖÆ 1000 0000
// dots in a line
for (k = 0, x = startx + 256; k < 8 && x < startx +8 + 256; k++, x+=1)//width - 1
{
if (p16 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
for (k = 0, x = startx +8 + 256; k < 8 && x < startx +16 + 256; k++, x+=1)//width - 1
{
if (p17 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
}
for (j = 0, y = starty; j < 16 && y < starty+16; j++, y+=1)//heigh - 1
{
//p16 = (unsigned short )table[(*p)*16+j];
p16 = (unsigned short )Chinese[2670*32+2*j];
p17 = (unsigned short )Chinese[2670*32+2*j+1];
mask16 = 0x0080; // ¶þœøÖÆ 1000 0000
// dots in a line
for (k = 0, x = startx + 16 + 256; k < 8 && x < startx + 16+8 + 256; k++, x+=1)//width - 1
{
if (p16 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
for (k = 0, x = startx + 16+8 + 256; k < 8 && x < startx + 16+16 + 256; k++, x+=1)//width - 1
{
if (p17 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
}
/* --------------------------汉字:方位-------------------------------------------------*/
// line dots per char
for (j = 0, y = starty; j < 16 && y < starty+16; j++, y+=1)//heigh - 1
{
//p16 = (unsigned short )table[(*p)*16+j];
p16 = (unsigned short )Chinese[2096*32+2*j];
p17 = (unsigned short )Chinese[2096*32+2*j+1];
mask16 = 0x0080; // ¶þœøÖÆ 1000 0000
// dots in a line
for (k = 0, x = startx + 384; k < 8 && x < startx +8 + 384; k++, x+=1)//width - 1
{
if (p16 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
for (k = 0, x = startx +8 + 384; k < 8 && x < startx +16 + 384; k++, x+=1)//width - 1
{
if (p17 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
}
for (j = 0, y = starty; j < 16 && y < starty+16; j++, y+=1)//heigh - 1
{
//p16 = (unsigned short )table[(*p)*16+j];
p16 = (unsigned short )Chinese[4256*32+2*j];
p17 = (unsigned short )Chinese[4256*32+2*j+1];
mask16 = 0x0080; // ¶þœøÖÆ 1000 0000
// dots in a line
for (k = 0, x = startx + 16 + 384; k < 8 && x < startx + 16+8 + 384; k++, x+=1)//width - 1
{
if (p16 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
for (k = 0, x = startx + 16+8 + 384; k < 8 && x < startx + 16+16 + 384; k++, x+=1)//width - 1
{
if (p17 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
}
/* --------------------------汉字:距离-------------------------------------------------*/
// line dots per char
for (j = 0, y = starty; j < 16 && y < starty+16; j++, y+=1)//heigh - 1
{
//p16 = (unsigned short )table[(*p)*16+j];
p16 = (unsigned short )Chinese[2789*32+2*j];
p17 = (unsigned short )Chinese[2789*32+2*j+1];
mask16 = 0x0080; // ¶þœøÖÆ 1000 0000
// dots in a line
for (k = 0, x = startx + 512; k < 8 && x < startx +8 + 512; k++, x+=1)//width - 1
{
if (p16 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
for (k = 0, x = startx +8 + 512; k < 8 && x < startx +16 + 512; k++, x+=1)//width - 1
{
if (p17 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
}
for (j = 0, y = starty; j < 16 && y < starty+16; j++, y+=1)//heigh - 1
{
//p16 = (unsigned short )table[(*p)*16+j];
p16 = (unsigned short )Chinese[2988*32+2*j];
p17 = (unsigned short )Chinese[2988*32+2*j+1];
mask16 = 0x0080; // ¶þœøÖÆ 1000 0000
// dots in a line
for (k = 0, x = startx + 16 + 512; k < 8 && x < startx + 16+8 + 512; k++, x+=1)//width - 1
{
if (p16 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
for (k = 0, x = startx + 16+8 + 512; k < 8 && x < startx + 16+16 + 512; k++, x+=1)//width - 1
{
if (p17 & (mask16 >> k))
{
*(offsetY + y*width + x) = tagY;
}
else
*(offsetY + y*width + x) = *(offsetY + y*width + x)*5/6 + 42;
}
}
return 0;
}