中文OSD显示机制
贺乐意
2023-12-01
在IP摄像机的实时视频流上面打上摄像机名称,公司logo和时间戳,就要用到OSD功能。
GM8126有四个osd win,在每个osd win中,支持的font是12x18点阵,32个char。
在这种条件下,如何实现下述功能:
1、OSD如何显示64个英文字母及+-/*:空格在内的字符组成的英文overlay。
2、如何让英文overlay大一点,12x16字体有点小。
3、如何分二行,三行显示overlay。
4、如何显示中文?中文的字体用24x24字库。
5、中文和英语用不同的字库,如何实现。
6、中文分两行显示。
上面的需求都可以实现,关键设计要点:
1、点阵动态加载,要显示的才加载入osd显存。
2、用2个或4个win来拼装显示bigger En or Zh。
3、既然有4个win,最多可以有4行。
4、动态生成字符点阵驱动,这样显示中文,英文或是任何一个图片都是可能的。
拼装一个24x24汉字关键算法:
ret=fread(&font, 1,96, fp); //读入这个汉字的点阵驱动,可以是根据汉字GM2312/BIG5字库来动态生成的。
if(ret != 96)
{
printf("Font corrupt!\n");ret=-3;break;
}
//win0显示汉字上面2个char
FontZhUpTable[FontUpCnt].font = ZhFontUpIndex; //生成汉字的index
memcpy(&FontZhUpTable[FontUpCnt].fbitmap[8],&font[0],24); //载入osd显存, win0
pWinUp[FontUpCnt]=ZhFontUpIndex; //要显示的char的index
FontUpCnt++;ZhFontUpIndex++;gFontCntAll++;
FontZhUpTable[FontUpCnt].font = ZhFontUpIndex; //一个汉字由4个char组成,所以index要不同
memcpy(&FontZhUpTable[FontUpCnt].fbitmap[8],&font[24],24); //载入osd win0
pWinUp[FontUpCnt]=ZhFontUpIndex;
FontUpCnt++;ZhFontUpIndex++;gFontCntAll++;
//win2显示汉字下面2个char
FontZhDnTable[FontDnCnt].font = ZhFontDnIndex;
memcpy(&FontZhUpTable[FontDnCnt].fbitmap[8],&font[48],24); //osd win2
pWinDn[FontDnCnt]=ZhFontDnIndex;
FontDnCnt++;ZhFontDnIndex++;gFontCntAll++;
FontZhDnTable[FontDnCnt].font = ZhFontDnIndex;
memcpy(&FontZhUpTable[FontDnCnt].fbitmap[8],&font[72],24); //osd win2
pWinDn[FontDnCnt]=ZhFontDnIndex;
FontDnCnt++;ZhFontDnIndex++;gFontCntAll++;
if (FontUpCnt>=OSD_4WIN_LEN) //continue to use win1&3,如果要显示的overlay比较长的话!
{
pWinUp=gZhTextWin1[ucStreamId];FontUpCnt=0;
pWinDn=gZhTextWin3[ucStreamId];FontDnCnt=0;
continue;
}
if (gFontCntAll>=OSD_2WIN_LEN)
{
ret=2;goto End;
}