一、字库字符实现OSD
1、原理讲解
位图填充支持两种实现方式:其一、用户通过HI_MPI_RGN_SetBitMap 接口将位图数据拷贝至内部显示画布;其二、用户通过 HI_MPI_RGN_GetCanvasInfo 获取内部备份显示画布的地址,直接对该地址数据进行更新,然后调用HI_MPI_RGN_UpdateCanvas 接口将备份显示画布更新为待显示画布,达到实现更新位图数据的目的。
在上篇文章中我们使用了方式二,并且直接使用bmp图片去显示,在这篇文章中我们将使用方式一,我们将使用海思提供的字模库先生成bmp图片数据再去显示。
实现的功能效果为:
2、代码框架分析
HH_OSD_Init //进行一些初始化并实现内容的显示
HH_OSD_SetOsdPosDefault //设置osd的坐标的,使用默认的位置
HH_OSD_GetOrg //获取进行显示位置的的坐标
HH_OSD_GetColor //获取颜色
HH_OSD_GetTitle //获取要显示的内容
HI_Create_Osd //创建一个显示logo,实例化一个用于显示的logo变量
HI_OSD_Build //创建osd结构体,创建位图,直接显示
HI_OSD_Parse_OsdTitle //解析osd字符,更新字符相关属性
HI_OSD_Get_BmpSize //根据ip_config配置的视频源的大小,来配置pOsdLogo中记录的OSD的字母的宽高、x,y坐标等
HI_Create_Osd_Reg //首先申请了OSD的bmp图片的内存buf,然后调用海思的RGN API来初始化overlay
HI_MPI_RGN_Create //创建osd
HI_MPI_RGN_AttachToChn //将osd与venc的通道绑定
HI_OSD_Create_Bitmap根据pOsdLogo记录的OSD要显示的内容,来生成bmp图片数据,然后调用HI_MPI_RGN_SetBitMap将这张BMP图片显示到OSD中
HI_OSD_CreateBMP // 用字库来生成bmp文件的
HI_MPI_RGN_SetBitMap // 真正设置osd显示的API
HI_OSD_Set_Show //根据传参show为true或者false来开启或关闭OSD的显示
HI_MPI_RGN_GetDisplayAttr //获取区域的通道显示属性
HI_MPI_RGN_SetDisplayAttr //设置区域的通道显示属性
HH_OSD_All_Refresh //手动去刷新显示的内容,实现时间的变化
HH_OSD_AllTime_Refresh
HH_OSD_ChnTime_Refresh
HH_OSD_ChName_Refresh
HH_OSD_GetLogoHandle
HH_OSD_GetTitle //获取显示的内容
HI_OSD_Parse_OsdTitle 解析osd的字符,更新字符相关属性
HI_OSD_Get_BmpSize
HI_OSD_Create_Bitmap
HI_OSD_CreateBMP
HI_MPI_RGN_SetBitMap
HH_OSD_Show_Refresh
HH_OSD_GetLogoHandle
HH_OSD_GetShow
HI_OSD_Set_Show //根据传参show为true或者false来开启或关闭OSD的显示
HH_OSD_AllName_Refresh
总结:字库字符实现OSD的本质原理是:先由字库生成对应文字内容的bmp文件,然后将bmp文件显示在osd中。
二、字库字符实现OSD源码解析
(1)主要文件
/**************************************************************************
* FileName: hh_hz16lib.c
* Description: HZ16 Matrix(汉字16点阵字库)
* Copyright(C): 2006-2008 HHDigital Inc.
* Version: V 1.0
* Author: ChenYG
* Created: 2006-08-06
* Updated:
* 一行一个汉字,一共8170,我们用的32字宽,所以这里是1个字符32个字节一行
**************************************************************************/
hh_osd.c处于hh_osd_api.c的上层,从各自文件中的函数名也可以看出,hh_osd.c中的以HH_开头,而hh_osd_api.c以HI_开头
(2)如何在字库中查取字模,使用汉字区位码(区码+位码,构成一个x,y坐标),汉字区位码是为每个汉字编一个唯一的代码,以便计算机辨认、接收和处理。
/******************************************************************************
* 函数名称: HH_OSD_DrawBitmapBit(hzPos, bitmap, fColor, bColor, bmpBuffer, fontSize)
* 功能描述: 将汉字的点阵转换为bmp写入缓冲区
* 其他说明:使用传入的区码和位码来查字模表,将查到的字模输出到in字符串中
*******************************************************************************/
int HI_OSD_DrawBitmapBit(int x_pos, HI_U8* bitmap, HI_U16 fColor,
HI_U16 bColor, HI_U16 edgeColor, HI_U8 *bmpBuffer, HI_U16 bmpWidth,
HI_U16 fontSize)
{
int i, j;
int w, h;
int startTop = 0;
unsigned char *pBuf = bmpBuffer;
unsigned short *pData = NULL;
unsigned char index;
int charwidth = 2;
int lineWidth = bmpWidth << 1;
int hzSize = 16;
int bZoom = 0;
startTop = 0;
if (fontSize <= 8)
{
hzSize = 8;
charwidth = 1;
}
else if (fontSize <= 12 || fontSize == 24)
{
hzSize = 12;
}
if (fontSize == 24 || fontSize == 32)
{
bZoom = 1;
}
for (i = 0; i < hzSize; i++)
{
w = (i + x_pos) << 1;
h = 0;
for (j = 0; j < hzSize; j++, startTop += charwidth)
{
index = (*(bitmap + startTop + (i>>3))) & (0x80>>(i&0x07)) ? 1: 0;
//index 有0 有1
//printf("\r\n === %d %d ===\r\n", h,w);
pData = (unsigned short *)((unsigned char *)pBuf + h + w);
if(index)
{
if (bZoom)
{
*pData = fColor;//fColor:文字颜色
*(pData + 1) = fColor;
*(pData + 2) = edgeColor; //edgeColor:文字边缘颜色,字放大看都是有边缘的
// *(pData + 3) = edgeColor;
*(pData + bmpWidth) = fColor;
*(pData + bmpWidth + 1) = fColor;
*(pData + bmpWidth + 2) = edgeColor;
// *(pData + bmpWidth + 1) = edgeColor;
}
else
{
*pData = fColor;
*(pData + 1) = edgeColor;
}
}
h += lineWidth * (bZoom + 1);
}
startTop = 0;
}
return 0;
}
本部分内容比较偏门和晦涩,只有专门去做这块内容的人才会研究的比较深,我们做到能大致看懂框架和简单使用即可。
注:本文章参考了《朱老师物联网大讲堂》课程笔记,并结合了自己的实际开发经历以及网上他人的技术文章,综合整理得到。如有侵权,联系删除!水平有限,欢迎各位在评论区交流。