易百纳论坛

 找回密码
 注册
搜索
热搜: 海思 四轴 linux
查看: 5794|回复: 45

FBI 叠加自定义中文字库 做OSD用,或者叠加其他信息

    [复制链接]
发表于 2016-6-16 15:03:07 | 显示全部楼层 |阅读模式
本帖最后由 ngswfx 于 2016-6-22 19:08 编辑

基本思路是:先把字库中的文字叠加到图片buffer上,叠加的时候如果能先得到背景的现在图片,最好了,就可以取反,这样任何光线环境都可以看清文字。
              然后再把这个图片以图形层的方式叠加到输出的主高清通道HD0上即可。
      中间生成文字图片的过程一次完成,可以在线程内执行,通常每秒处理一次即可。这样就可以实现OSD时间,各种文字信息的叠加。

我这边实现的是整个Debug调试信息的叠加,有20行。
   
由于代码在我的整个项目内,还没有搞清爽,所以摘主要关键的传上来大家参考。

其他的部分,参考SDK里面的那个叠加llogo图片的例子,注意把背景色都弄成黑色0x0即可,透出输出的视频了。

附件中,有汉字的字库,本文仅仅使用HZ16Lib.c即可,直接添加到自己的工程里就可以了。如果嫌弃自体小,还可以找24或者32的字库,基础图片可以小一倍,然后叠加时,对缓冲进行放大,要用到那个TDE处理一下缩放,这样效率高些。

我这边输出现在是1024*768,图片用的也是1024*768,所以没用TDE缩放,效率没问题,3520速度很快,我叠加了20行debug信息,都没事,每秒才处理1次。




  1.     #define                                 USE_CHINESE_WORD_LIB_OSD
  2.     #define                                        HZLIB_ZISE                16
  3.     #define                                        UInt32        unsigned int
  4.     #define                                        UInt16        unsigned short
  5.     #define                                        UInt8        unsigned char
  6.     #define                                        Int8        char
  7.     #define                                        CLIP(a,b,c)    (((a)<(b))?(b):(((a)>(c))?(c):(a)))
  8.     #define                                        UCLIPI(a,b)    CLIP(a,0,b)
  9.     #define                                        HZLIB_ZISE                16
  10.     #define                                        MUX(a,b,c)     ((a)?(b):(c))
  11.     #define                                        INONZERO(a,b)     MUX(a,0,b)
  12.     #define                                        UBYTESEL(a, n)        ( (a>>(8*n)) && 0xff)
  13.     extern int                         g_real_HZ16_count;
  14.     extern unsigned short HZ16_Space[];
  15.     extern unsigned char         HZ16Lib[];

  16.     #define MAX_SUPPORT_OSD_LINES                           4
  17.     #define MAX_SUPPORT_OSD_CHAR_NUM_ONE_LINE  32   //一行最大支持的字符数目
  18.     typedef struct IVHI_OSDEX
  19.     {
  20.             bool bUse;//用于高速判断用
  21.             int  nDisplay;//哪个显示器,第几个输出通道,对于3520等,只有一个,所以为0
  22.             int  nChl;//这个指的是某个显示通道,例如某个屏幕上的某个画面
  23.             int  nSupportLines;//支持的行数
  24.             int  nPosX[MAX_SUPPORT_OSD_LINES];//坐标
  25.             int  nPosY[MAX_SUPPORT_OSD_LINES];
  26.             int  nColor[MAX_SUPPORT_OSD_LINES];//字符颜色
  27.             char strInf[MAX_SUPPORT_OSD_LINES][MAX_SUPPORT_OSD_CHAR_NUM_ONE_LINE];
  28.     }IVHI_OSD;
  29.     IVHI_OSD                                                                                        videoChlOsd[MAX_SUPPORT_DEC_VIDEO_CHL];
  30.     int                                 fdOSD                                                        =0;
  31.     char *                                pOSDYuv                                                        =NULL;
  32.     HIFB_BUFFER_S                 stOsdCanvasBuf;
  33.     HI_U16 *                        pOSDBuf=NULL;
  34.     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  35.     #define BK_SCR_TRANS_COLOR_KEY                                                 0x01   //背景透明色

  36.     void YtoRGB1555ToChar(unsigned char Y,unsigned char *rgb1555_0,unsigned char *rgb1555_1,int nColor)
  37.     {
  38.             if(Y>0x01){
  39.                     Y=0xF0;
  40.                     switch(nColor){
  41.                     case 0://白色
  42.                             *rgb1555_0=0xFF;
  43.                             *rgb1555_1=0xFF;
  44.                     break;
  45.                     case 1://
  46.                             *rgb1555_0=0x80;
  47.                             *rgb1555_1=0x80;
  48.                             break;
  49.                     case 2:
  50.                             *rgb1555_0=0xFF;
  51.                             *rgb1555_1=0x80;
  52.                             break;
  53.                     case 3:
  54.                             *rgb1555_0=0x14;
  55.                             *rgb1555_1=0x14;
  56.                             break;
  57.                     }
  58.                     return;
  59.             }
  60.     }

  61.     void DrawOSD(unsigned char *buf, unsigned short *hzLib,int stride,int nColor)
  62.     {
  63.             int i, font;
  64.             int        lumi;
  65.             bool lum=true;
  66.             int *p1 = (int *)(buf+(stride<<4));
  67.             float mult_f = (float)(lum?0.20:1);
  68.             mult_f=0.5;
  69.             float mult_b = 1 - mult_f;
  70.             int avglum = (buf[0] + buf[1] + buf[2] + buf[3] + buf[4] +buf[5] + buf[6] + buf[7] + buf[8] + buf[9] + buf[10] +buf[11] + buf[12] + buf[13] + buf[14] + buf[15])/16;
  71.             if(!lum&&(avglum>145))
  72.                     lumi = 0x1;
  73.             else
  74.                     lumi = 0xff;
  75.             //1字节个亮度信息转为2字节1555
  76.             int nD=2;//翻倍
  77.             unsigned short Y;
  78.             int nPos=0;
  79.             for (i=0; i<16; i++) {
  80.                     font = *hzLib ++;
  81.                     ///////////////  这里修改一下,如果开始的buf里面是背景数据的话,通过调整上面的几个参数可以实现取反,主要是avglum的作用,它先计算开始的数据情况,然后如果背景亮度大于145就变黑,我没搞到视频数据,所以暂时没实现,这里有点乱
  82.             //        for (int j=0; j<32; j++) {
  83.             //                buf[j]=BK_SCR_TRANS_COLOR_KEY;
  84.             //        }
  85.                     nPos=0;//buf[0*nD]和buf[0*nD+1] 2个字节就是1555
  86.                     Y   = (unsigned char)MUX(font&0x0080, lumi*mult_f+buf[0*nD]*mult_b, buf[0*nD]); //这个就是一个Y 变成1555 2个字节
  87.                     YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  88.                     nPos=1;
  89.                     Y   = (unsigned char)MUX(font&0x0040, lumi*mult_f+buf[1*nD]*mult_b, buf[1*nD]);
  90.                     YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  91.                     nPos=2;
  92.                     Y   = (unsigned char)MUX(font&0x0020, lumi*mult_f+buf[2*nD]*mult_b, buf[2*nD]);
  93.                     YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  94.                     nPos=3;
  95.                     Y   = (unsigned char)MUX(font&0x0010, lumi*mult_f+buf[3*nD]*mult_b, buf[3*nD]);
  96.                     YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  97.                     nPos=4;
  98.                     Y   = (unsigned char)MUX(font&0x0008, lumi*mult_f+buf[4*nD]*mult_b, buf[4*nD]);
  99.                     YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  100.                     nPos=5;
  101.                     Y   = (unsigned char)MUX(font&0x0004, lumi*mult_f+buf[5*nD]*mult_b,buf[5*nD]);
  102.                     YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  103.                     nPos=6;
  104.                     Y   = (unsigned char)MUX(font&0x0002, lumi*mult_f+buf[6*nD]*mult_b,buf[6*nD]);
  105.                     YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  106.                     nPos=7;
  107.                     Y   = (unsigned char)MUX(font&0x0001, lumi*mult_f+buf[7*nD]*mult_b,buf[7*nD]);
  108.                     YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  109.                     nPos=8;
  110.                     Y   = (unsigned char)MUX(font&0x8000, lumi*mult_f+buf[8*nD]*mult_b,buf[8*nD]);
  111.                     YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  112.                     nPos=9;
  113.                     Y   = (unsigned char)MUX(font&0x4000, lumi*mult_f+buf[9*nD]*mult_b,buf[9*nD]);
  114.                     YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  115.                     nPos=10;
  116.                     Y = (unsigned char)MUX(font&0x2000, lumi*mult_f+buf[10*nD]*mult_b,  buf[10*nD]);
  117.                     YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  118.                     nPos=11;
  119.                     Y = (unsigned char)MUX(font&0x1000, lumi*mult_f+buf[11*nD]*mult_b,  buf[11*nD]);
  120.                     YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  121.                     nPos=12;
  122.                     Y = (unsigned char)MUX(font&0x0800, lumi*mult_f+buf[12*nD]*mult_b,  buf[12*nD]);
  123.                     YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  124.                     nPos=13;
  125.                     Y = (unsigned char)MUX(font&0x0400, lumi*mult_f+buf[13*nD]*mult_b,  buf[13*nD]);
  126.                     YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  127.                     nPos=14;
  128.                     Y = (unsigned char)MUX(font&0x0200, lumi*mult_f+buf[14*nD]*mult_b,  buf[14*nD]);
  129.                     YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  130.                     nPos=15;
  131.                     Y = (unsigned char)MUX(font&0x0100, lumi*mult_f+buf[15*nD]*mult_b,  buf[15*nD]);
  132.                     YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  133.                     /////////////////////////////////////////
  134.                     buf += stride*2;
  135.             }

  136.     }
  137.     int        ShowOSD_MX(unsigned char *pBase, char *pStr, unsigned short x, unsigned short y,int width, int height,int nColor)
  138.     {
  139.             if(!pBase||!pStr||width<1||height<1||x>width||y>=height)
  140.                     return 0;
  141.             UInt32 nChar=0,wd=0,nOffset=0,nSize, l, r;
  142.     #if defined USE_CHINESE_WORD_LIB_OSD
  143.             Int8 q=3;
  144.             Int8 w;
  145.             Int8 *p=(char *)pStr;
  146.             UInt8 *pHZLib=0;
  147.             UInt8        *pp = (unsigned char *)p;
  148.             pBase += width*2*y+x*2;
  149.             while (*p) {
  150.                     pp = (unsigned char *)p;
  151.                     q = *p&0x80?(*p++)-161:2; // Get qu code
  152.                     w=((*p++)&0x7f)-33; // Get wei code
  153.                     if ((int)(nOffset = q*94+w) >= g_real_HZ16_count)
  154.                             continue;
  155.                     pHZLib = (HZ16Lib+(nOffset<<5));
  156.                     if (q<10) {
  157.                             l = UBYTESEL(HZ16_Space[nOffset],1);
  158.                             r = UBYTESEL(HZ16_Space[nOffset],0);
  159.                             nSize = HZLIB_ZISE-(l+r);
  160.                     }
  161.                     else {
  162.                             nSize = HZLIB_ZISE;
  163.                             l = r = 0;
  164.                     }
  165.                     if ((int)(x+wd+nSize)>width)
  166.                             break;
  167.                     DrawOSD(pBase+(wd+nChar)*2,(unsigned short *)pHZLib,width,nColor);
  168.                     nChar++;
  169.                     wd += 14;//12 自体间距
  170.             }
  171.     #endif
  172.             return nChar;
  173.     }

  174.     void ShowSysWorkInfOSD()
  175.     {
  176.             if(!pOSDYuv)
  177.                     return;
  178.             //DebugInfEx(DBG_LEVEL1,"ShowSysWorkInfOSD in %d\n",GetTickCount());
  179.             //CPU
  180.             int nLineDisY=16;
  181.             int nLineDisX=16;
  182.             int nPosYAdd=20;
  183.             SYSTEMTIME sysTime;
  184.             GetLocalTime(&sysTime);
  185.             char strINF[MAX_SUPPORT_OSD_DEBUG_INF_CHAR_NUM];
  186.             memset(strINF,0,sizeof strINF);
  187.             sprintf(strINF,"CPU:%d%",IVComInf_GetCpuPercent());
  188.             ShowOSD_MX((unsigned char *)pOSDYuv,strINF,nLineDisX,nLineDisY,nWndWidth,nWndHeight,0);
  189.             //内存
  190.             nLineDisY+=nPosYAdd;
  191.             memset(strINF,0,sizeof strINF);
  192.             sprintf(strINF,"MEM:%d%",IVComInf_GetMemPercent());
  193.             ShowOSD_MX((unsigned char *)pOSDYuv,strINF,nLineDisX,nLineDisY,nWndWidth,nWndHeight,0);
  194.             //网络
  195.             nLineDisY+=nPosYAdd;
  196.             memset(strINF,0,sizeof strINF);
  197.             char strNetCardName[32];
  198.             char strIP[32];
  199.             char strMask[32];
  200.             char strGate[32];
  201.             IVComInf_GetLocalNetPara(0,strNetCardName,strIP,strMask,strGate,NULL);
  202.             sprintf(strINF,"NET:%d%",IVComInf_GetNetPercent(),strNetCardName,strIP,strMask,strGate);
  203.             ShowOSD_MX((unsigned char *)pOSDYuv,strINF,nLineDisX,nLineDisY,nWndWidth,nWndHeight,0);
  204.             //硬盘 FLASH
  205.             nLineDisY+=nPosYAdd;
  206.             memset(strINF,0,sizeof strINF);
  207.             sprintf(strINF,"DISK:16M (32M)");
  208.             ShowOSD_MX((unsigned char *)pOSDYuv,strINF,nLineDisX,nLineDisY,nWndWidth,nWndHeight,0);
  209.             //通道总数
  210.             nLineDisY+=nPosYAdd;
  211.             memset(strINF,0,sizeof strINF);
  212.             sprintf(strINF,"通道总数:4");
  213.             ShowOSD_MX((unsigned char *)pOSDYuv,strINF,nLineDisX,nLineDisY,nWndWidth,nWndHeight,0);
  214.             //分割数
  215.             nLineDisY+=nPosYAdd;
  216.             memset(strINF,0,sizeof strINF);
  217.             sprintf(strINF,"分割数:4");
  218.             ShowOSD_MX((unsigned char *)pOSDYuv,strINF,nLineDisX,nLineDisY,nWndWidth,nWndHeight,0);
  219.             //时间
  220.             nLineDisY+=nPosYAdd;
  221.             memset(strINF,0,sizeof strINF);
  222.             sprintf(strINF,"TIME:%04d-%02d-%02d/%02d:%02d:%02d-%d\n",sysTime.wYear,sysTime.wMonth,sysTime.wDay,sysTime.wHour,sysTime.wMinute,sysTime.wSecond,GetTickCount());
  223.             ShowOSD_MX((unsigned char *)pOSDYuv,strINF,nLineDisX,nLineDisY,nWndWidth,nWndHeight,0);
  224.             //return ;
  225.             //DEBUG 信息
  226.             nLineDisY=nWndHeight-32;
  227.             for(int i=0;i<MAX_SUPPORT_OSD_DEBUG_INF_LIST_NUM;i++){
  228.                     if(strlen(lastDebugString[i])>0){
  229.                             memset(strINF,0,sizeof strINF);
  230.                             sprintf(strINF,"%s",lastDebugString[i]);
  231.                             ShowOSD_MX((unsigned char *)pOSDYuv,strINF,nLineDisX,nLineDisY,nWndWidth,nWndHeight,0);
  232.                             nLineDisY-=nPosYAdd;
  233.                     }
  234.             }
  235.     }

  236.     /////////////////////////////////
  237.     void Check_DeInitOSD()
  238.     {
  239.             if(!bCanUseOSD)
  240.                     return;
  241.             bCanUseOSD=false;
  242.             if(fdOSD){
  243.                     close(fdOSD);
  244.                     fdOSD=0;
  245.             }
  246.             if(stOsdCanvasBuf.stCanvas.u32PhyAddr){
  247.                     HI_MPI_SYS_MmzFree(stOsdCanvasBuf.stCanvas.u32PhyAddr, pOSDBuf);
  248.                     stOsdCanvasBuf.stCanvas.u32PhyAddr=NULL;
  249.                     pOSDBuf=NULL;
  250.                     memset(&stOsdCanvasBuf,0,sizeof stOsdCanvasBuf);
  251.             }
  252.             if(pOSDYuv){
  253.                     delete pOSDYuv;
  254.                     pOSDYuv=NULL;
  255.             }
  256.     }
  257.     int Check_InitOSD_ENV()
  258.     {
  259.             if(fdOSD!=0)
  260.                     return fdOSD;
  261.             ////////////////////////////////////////////////
  262.             HI_S32 s32Ret =         HI_SUCCESS;
  263.             HIFB_LAYER_INFO_S         stLayerInfo;
  264.             HI_BOOL                         Show;
  265.             HI_BOOL                         bCompress = HI_TRUE;
  266.             HIFB_POINT_S stPoint = {0};
  267.             struct fb_var_screeninfo stVarInfo;
  268.             char file[12] = "/dev/fb0";
  269.             HIFB_COLORKEY_S         stColorKey;
  270.             HI_U32                                 maxW,maxH,u32Frm;//指的是屏幕宽度高度
  271.             //////////////////////////////////////////
  272.             strcpy(file, "/dev/fb0");
  273.             fdOSD = open(file, O_RDWR, 0);
  274.             if(fdOSD < 0)
  275.                     return 0;
  276.             if (ioctl(fdOSD, FBIOPUT_COMPRESSION_HIFB, &bCompress) < 0)
  277.             {
  278.                     close(fdOSD);fdOSD=0;
  279.                     return 0;
  280.             }
  281.             stColorKey.bKeyEnable = HI_TRUE;
  282.             stColorKey.u32Key = BK_SCR_TRANS_COLOR_KEY;
  283.             if (ioctl(fdOSD, FBIOPUT_COLORKEY_HIFB, &stColorKey) < 0)
  284.             {
  285.                     close(fdOSD);fdOSD=0;
  286.                     return 0;
  287.             }
  288.             s32Ret = ioctl(fdOSD, FBIOGET_VSCREENINFO, &stVarInfo);
  289.             if(s32Ret < 0){
  290.                     close(fdOSD);fdOSD=0;
  291.                     return 0;
  292.             }
  293.             if (ioctl(fdOSD, FBIOPUT_SCREEN_ORIGIN_HIFB, &stPoint) < 0){
  294.                     close(fdOSD);fdOSD=0;
  295.                     return 0;
  296.             }
  297.             SAMPLE_COMM_VO_GetWH(VIDOE_OUT_RESOLUTION, &maxW,&maxH,&u32Frm);
  298.             stVarInfo.xres = stVarInfo.xres_virtual = maxW;
  299.             stVarInfo.yres = stVarInfo.yres_virtual = maxH;
  300.             s32Ret = ioctl(fdOSD, FBIOPUT_VSCREENINFO, &stVarInfo);
  301.             if(s32Ret < 0){
  302.                     close(fdOSD);fdOSD=0;
  303.                     return 0;
  304.             }
  305.             stLayerInfo.BufMode = HIFB_LAYER_BUF_ONE;
  306.             stLayerInfo.u32Mask = HIFB_LAYERMASK_BUFMODE; // HIFB_LAYERMASK_BUFMODE HIFB_LAYERMASK_ANTIFLICKER_MODE
  307.             s32Ret = ioctl(fdOSD, FBIOPUT_LAYER_INFO, &stLayerInfo);
  308.             if(s32Ret < 0){
  309.                     close(fdOSD);fdOSD=0;
  310.                     return 0;
  311.             }
  312.             Show = HI_TRUE;
  313.             if (ioctl(fdOSD, FBIOPUT_SHOW_HIFB, &Show) < 0){
  314.                     close(fdOSD);fdOSD=0;
  315.                     return 0;
  316.             }
  317.             if (HI_FAILURE == HI_MPI_SYS_MmzAlloc(&(stOsdCanvasBuf.stCanvas.u32PhyAddr), ((void**)&pOSDBuf),NULL, NULL, maxW*maxH*2)){
  318.                     close(fdOSD);fdOSD=0;
  319.                     return 0;
  320.             }
  321.             stOsdCanvasBuf.stCanvas.u32Height = maxH;
  322.             stOsdCanvasBuf.stCanvas.u32Width = maxW;
  323.             stOsdCanvasBuf.stCanvas.u32Pitch = maxW*2;
  324.             stOsdCanvasBuf.stCanvas.enFmt = HIFB_FMT_ARGB1555;//HIFB_FMT_RGB565 HIFB_FMT_ARGB1555 HIFB_FMT_RGB888
  325.             memset(pOSDBuf, BK_SCR_TRANS_COLOR_KEY, stOsdCanvasBuf.stCanvas.u32Pitch*stOsdCanvasBuf.stCanvas.u32Height);
  326.             if(!pOSDYuv)
  327.                     pOSDYuv=new char[maxW*maxH*2];
  328.         return fdOSD;
  329.     }
复制代码



//////先调用Check_InitOSD_ENV()准备好OSD 的FBI环境,然后调用ShowSysWorkInfOSD()就看到中文字了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
 楼主| 发表于 2016-6-17 16:43:33 | 显示全部楼层
3520D HIFB 叠加中文效果图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
 楼主| 发表于 2016-6-17 19:12:32 | 显示全部楼层
,多谢版主,还是加精挣钱快。
发表于 2016-6-18 18:38:06 | 显示全部楼层
ngswfx 发表于 2016-6-17 19:12
,多谢版主,还是加精挣钱快。

应该的,发的贴很棒,当然要加精!
发表于 2016-6-19 16:13:11 | 显示全部楼层
真的很好,多谢
发表于 2016-6-20 11:21:59 | 显示全部楼层
本帖最后由 love_lin 于 2016-6-20 11:29 编辑

至于上周六我提出来的背景半透明,以后我会慢慢研究。然而我就是连续调用你的几个函数接口,还是没办法显示中文,代码如下:
//请帮忙看下是什么原因,调用您的接口都没有变化的,查了半天还是不知道为何,只是把您的字库换成头文件来调用,应该也是可以的!!
  1. /*
  2. * =====================================================
  3. *
  4. *       Filename:  osd_menu.c
  5. *
  6. *    Description:  osd menu
  7. *
  8. *        Version:  
  9. *        Created:  2016年06月03日 10时03分32秒
  10. *       Revision:  none
  11. *       Compiler:  arm-hisiv300-linux-gcc
  12. *
  13. *         Author:  CharLee
  14. *   Organization:  Xiamen CloudTop Technology Co.,LTD
  15. *
  16. * =====================================================
  17. */

  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <sys/types.h>
  22. #include <sys/stat.h>
  23. #include <sys/ioctl.h>
  24. #include <sys/poll.h>
  25. #include <sys/time.h>
  26. #include <fcntl.h>
  27. #include <errno.h>
  28. #include <pthread.h>
  29. #include <math.h>
  30. #include <unistd.h>
  31. #include <signal.h>
  32. #include <sys/mman.h>
  33. #include <stdbool.h>

  34. #include "sample_comm.h"

  35. #include <linux/fb.h>
  36. #include "hifb.h"
  37. #include "loadbmp.h"
  38. #include "hi_tde_api.h"
  39. #include "hi_tde_type.h"
  40. #include "hi_tde_errcode.h"
  41. #include "HZ16Lib.h"

  42. #define WIDTH_1920             1920
  43. #define HEIGHT_1080            1080
  44. #define WIDTH_720              720
  45. #define HEIGHT_576             576

  46. #define SAMPLE_IMAGE_WIDTH     720
  47. #define SAMPLE_IMAGE_HEIGHT    576
  48. #define SAMPLE_IMAGE_SIZE      (720*576*2)
  49. #define SAMPLE_IMAGE_NUM       20
  50. #define HIFB_RED_1555   0xFC00

  51. #define GRAPHICS_LAYER_G0  0

  52. #define                                        HZLIB_ZISE                16
  53. #define                                        UInt32        unsigned int
  54. #define                                        UInt16        unsigned short
  55. #define                                        UInt8        unsigned char
  56. #define                                        Int8        char
  57. #define                                        CLIP(a,b,c)    (((a)<(b))?(b):(((a)>(c))?(c):(a)))
  58. #define                                        UCLIPI(a,b)    CLIP(a,0,b)
  59. //#define                                        HZLIB_ZISE                16
  60. #define                                        MUX(a,b,c)     ((a)?(b):(c))
  61. #define                                        INONZERO(a,b)     MUX(a,0,b)
  62. #define                                        UBYTESEL(a, n)        ( (a>>(8*n)) && 0xff)

  63. static struct fb_bitfield s_r16 = {10, 5, 0};
  64. static struct fb_bitfield s_g16 = {5, 5, 0};
  65. static struct fb_bitfield s_b16 = {0, 5, 0};
  66. static struct fb_bitfield s_a16 = {15, 1, 0};


  67. //#define MAX_SUPPORT_DEC_VIDEO_CHL 1
  68. //#define MAX_SUPPORT_OSD_LINES                           4
  69. //#define MAX_SUPPORT_OSD_CHAR_NUM_ONE_LINE  32   //一行最大支持的字符数目

  70. char * pOSDRGB = NULL;

  71. void YtoRGB1555ToChar(unsigned char Y,unsigned char *rgb1555_0,unsigned char *rgb1555_1,int nColor)
  72. {
  73.     if(Y>0x01){
  74.             Y=0xF0;
  75.             switch(nColor){
  76.             case 0://白色
  77.                     *rgb1555_0=0xFF;
  78.                     *rgb1555_1=0xFF;
  79.             break;
  80.             case 1://
  81.                     *rgb1555_0=0x80;
  82.                     *rgb1555_1=0x80;
  83.                     break;
  84.             case 2:
  85.                     *rgb1555_0=0xFF;
  86.                     *rgb1555_1=0x80;
  87.                     break;
  88.             case 3:
  89.                     *rgb1555_0=0x14;
  90.                     *rgb1555_1=0x14;
  91.                     break;
  92.             }
  93.             return;
  94.     }
  95. }

  96. void DrawOSD(unsigned char *buf, unsigned short *hzLib,int stride,int nColor)
  97. {
  98.     int i, font;
  99.     int        lumi;
  100.     bool lum=true;
  101.     int *p1 = (int *)(buf+(stride<<4));
  102.     float mult_f = (float)(lum?0.20:1);
  103.     mult_f=0.5;
  104.     float mult_b = 1 - mult_f;
  105.     int avglum = (buf[0] + buf[1] + buf[2] + buf[3] + buf[4] +buf[5] + buf[6] + buf[7] + buf[8] + buf[9] + buf[10] +buf[11] + buf[12] + buf[13] + buf[14] + buf[15])/16;
  106.     if(!lum&&(avglum>145))
  107.             lumi = 0x1;
  108.     else
  109.             lumi = 0xff;
  110.     //1字节个亮度信息转为2字节1555
  111.     int nD=2;//翻倍
  112.     unsigned short Y;
  113.     int nPos=0;
  114.     for (i=0; i<16; i++) {
  115.             font = *hzLib ++;
  116.             nPos=0;//buf[0*nD]和buf[0*nD+1] 2个字节就是1555
  117.             Y   = (unsigned char)MUX(font&0x0080, lumi*mult_f+buf[0*nD]*mult_b, buf[0*nD]); //这个就是一个Y 变成1555 2个字节
  118.             YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  119.             nPos=1;
  120.             Y   = (unsigned char)MUX(font&0x0040, lumi*mult_f+buf[1*nD]*mult_b, buf[1*nD]);
  121.             YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  122.             nPos=2;
  123.             Y   = (unsigned char)MUX(font&0x0020, lumi*mult_f+buf[2*nD]*mult_b, buf[2*nD]);
  124.             YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  125.             nPos=3;
  126.             Y   = (unsigned char)MUX(font&0x0010, lumi*mult_f+buf[3*nD]*mult_b, buf[3*nD]);
  127.             YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  128.             nPos=4;
  129.             Y   = (unsigned char)MUX(font&0x0008, lumi*mult_f+buf[4*nD]*mult_b, buf[4*nD]);
  130.             YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  131.             nPos=5;
  132.             Y   = (unsigned char)MUX(font&0x0004, lumi*mult_f+buf[5*nD]*mult_b,buf[5*nD]);
  133.             YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  134.             nPos=6;
  135.             Y   = (unsigned char)MUX(font&0x0002, lumi*mult_f+buf[6*nD]*mult_b,buf[6*nD]);
  136.             YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  137.             nPos=7;
  138.             Y   = (unsigned char)MUX(font&0x0001, lumi*mult_f+buf[7*nD]*mult_b,buf[7*nD]);
  139.             YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  140.             nPos=8;
  141.             Y   = (unsigned char)MUX(font&0x8000, lumi*mult_f+buf[8*nD]*mult_b,buf[8*nD]);
  142.             YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  143.             nPos=9;
  144.             Y   = (unsigned char)MUX(font&0x4000, lumi*mult_f+buf[9*nD]*mult_b,buf[9*nD]);
  145.             YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  146.             nPos=10;
  147.             Y = (unsigned char)MUX(font&0x2000, lumi*mult_f+buf[10*nD]*mult_b,  buf[10*nD]);
  148.             YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  149.             nPos=11;
  150.             Y = (unsigned char)MUX(font&0x1000, lumi*mult_f+buf[11*nD]*mult_b,  buf[11*nD]);
  151.             YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  152.             nPos=12;
  153.             Y = (unsigned char)MUX(font&0x0800, lumi*mult_f+buf[12*nD]*mult_b,  buf[12*nD]);
  154.             YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  155.             nPos=13;
  156.             Y = (unsigned char)MUX(font&0x0400, lumi*mult_f+buf[13*nD]*mult_b,  buf[13*nD]);
  157.             YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  158.             nPos=14;
  159.             Y = (unsigned char)MUX(font&0x0200, lumi*mult_f+buf[14*nD]*mult_b,  buf[14*nD]);
  160.             YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  161.             nPos=15;
  162.             Y = (unsigned char)MUX(font&0x0100, lumi*mult_f+buf[15*nD]*mult_b,  buf[15*nD]);
  163.             YtoRGB1555ToChar(Y,buf+nPos*nD,buf+nPos*nD+1,nColor);
  164.             
  165.                         buf += stride*2;
  166.     }

  167. }
  168. int  ShowOSD_DEC_BOX_MX(unsigned char *pBase, char *pStr, unsigned short x, unsigned short y,int width, int height,int nColor)
  169. {
  170.     if(!pBase||!pStr||width<1||height<1||x>width||y>=height)
  171.             return 0;
  172.     UInt32 nChar=0,wd=0,nOffset=0,nSize, l, r;

  173.     Int8 q=3;
  174.     Int8 w;
  175.     Int8 *p=(char *)pStr;
  176.     UInt8 *pHZLib=0;
  177.     UInt8        *pp = (unsigned char *)p;
  178.     pBase += width*2*y+x*2;
  179.     while (*p) {
  180.             pp = (unsigned char *)p;
  181.             q = *p&0x80?(*p++)-161:2; // Get qu code
  182.             w=((*p++)&0x7f)-33; // Get wei code
  183.             if ((int)(nOffset = q*94+w) >= g_real_HZ16_count)
  184.                     continue;
  185.             pHZLib = (HZ16Lib+(nOffset<<5));
  186.             if (q<10) {
  187.                     l = UBYTESEL(HZ16_Space[nOffset],1);
  188.                     r = UBYTESEL(HZ16_Space[nOffset],0);
  189.                     nSize = HZLIB_ZISE-(l+r);
  190.             }
  191.             else {
  192.                     nSize = HZLIB_ZISE;
  193.                     l = r = 0;
  194.             }
  195.             if ((int)(x+wd+nSize)>width)
  196.                     break;
  197.             DrawOSD(pBase+(wd+nChar)*2,(unsigned short *)pHZLib,width,nColor);
  198.             nChar++;
  199.             wd += 14;//12 自体间距
  200.     }

  201.     return nChar;
  202. }

  203. static int OSD_MENU_Init()
  204. {
  205.         int nWndWidth = WIDTH_720;
  206.         int nWndHeight = HEIGHT_576;
  207.         ShowOSD_DEC_BOX_MX((unsigned char *)pOSDRGB,"IP:192.168.0.27",128,64,nWndWidth,nWndHeight,0);
  208.         ShowOSD_DEC_BOX_MX((unsigned char *)pOSDRGB,"OSD 菜单",128,128,nWndWidth,nWndHeight,0);
  209.         ShowOSD_DEC_BOX_MX((unsigned char *)pOSDRGB,"CloudTop@CharLee",128,192,nWndWidth,nWndHeight,0);
  210.         ShowOSD_DEC_BOX_MX((unsigned char *)pOSDRGB,"通道号(chl): 0",128,256,nWndWidth,nWndHeight,0);
  211.         ShowOSD_DEC_BOX_MX((unsigned char *)pOSDRGB,"中文测试,能否正常显示",128,320,nWndWidth,nWndHeight,2);
  212.         return 0;
  213. }

  214. HI_S32 OSD_MENU_HIFB_Refresh()
  215. {
  216.     HI_S32 s32Ret = HI_SUCCESS;
  217.     HIFB_LAYER_INFO_S stLayerInfo = {0};
  218.     HIFB_BUFFER_S stCanvasBuf;
  219.     HI_U16* pBuf;
  220.     HI_U8* pDst = NULL;
  221.     //HI_U32 x;
  222.     //HI_U32 y;
  223.     //HI_U32 i;
  224.     HI_CHAR image_name[128];
  225.     HI_BOOL bShow;
  226.     HIFB_POINT_S stPoint = {0};
  227.     struct fb_var_screeninfo stVarInfo;
  228.     HI_CHAR file[12] = "/dev/fb0";
  229.     HI_U32 maxW;
  230.     HI_U32 maxH;
  231.         int fd;
  232.     HIFB_COLORKEY_S stColorKey;
  233.     TDE2_RECT_S stSrcRect, stDstRect;
  234.     TDE2_SURFACE_S stSrc, stDst;
  235.     HI_U32 Phyaddr;
  236.     TDE_HANDLE s32Handle;

  237.     fd = open("/dev/fb0", O_RDWR, 0);
  238.     if (fd < 0)
  239.     {
  240.         SAMPLE_PRT("open %s failed!\n", file);
  241.         return HI_NULL;
  242.     }
  243.     /*all layer surport colorkey*/
  244.     stColorKey.bKeyEnable = HI_TRUE;
  245.     stColorKey.u32Key = 0x0;
  246.     if (ioctl(fd, FBIOPUT_COLORKEY_HIFB, &stColorKey) < 0)
  247.     {
  248.         SAMPLE_PRT("FBIOPUT_COLORKEY_HIFB!\n");
  249.         close(fd);
  250.         return HI_NULL;
  251.     }
  252.     s32Ret = ioctl(fd, FBIOGET_VSCREENINFO, &stVarInfo);
  253.     if (s32Ret < 0)
  254.     {
  255.         SAMPLE_PRT("GET_VSCREENINFO failed!\n");
  256.         close(fd);
  257.         return HI_NULL;
  258.     }

  259.     if (ioctl(fd, FBIOPUT_SCREEN_ORIGIN_HIFB, &stPoint) < 0)
  260.     {
  261.         SAMPLE_PRT("set screen original show position failed!\n");
  262.         close(fd);
  263.         return HI_NULL;
  264.     }

  265.         maxW = WIDTH_720;
  266.     maxH = HEIGHT_576;

  267.     stVarInfo.transp = s_a16;
  268.     stVarInfo.red = s_r16;
  269.     stVarInfo.green = s_g16;
  270.     stVarInfo.blue = s_b16;
  271.     stVarInfo.bits_per_pixel = 16;
  272.     stVarInfo.activate = FB_ACTIVATE_NOW;
  273.     stVarInfo.xres = stVarInfo.xres_virtual = maxW;
  274.     stVarInfo.yres = stVarInfo.yres_virtual = maxH;
  275.     s32Ret = ioctl(fd, FBIOPUT_VSCREENINFO, &stVarInfo);
  276.     if (s32Ret < 0)
  277.     {
  278.         SAMPLE_PRT("PUT_VSCREENINFO failed!\n");
  279.         close(fd);
  280.         return HI_NULL;
  281.     }
  282.     stLayerInfo.BufMode = HIFB_LAYER_BUF_NONE;
  283.     stLayerInfo.u32Mask = HIFB_LAYERMASK_BUFMODE;

  284.     s32Ret = ioctl(fd, FBIOPUT_LAYER_INFO, &stLayerInfo);
  285.     if (s32Ret < 0)
  286.     {
  287.         SAMPLE_PRT("PUT_LAYER_INFO failed!\n");
  288.         close(fd);
  289.         return HI_NULL;
  290.     }
  291.     bShow = HI_TRUE;
  292.     if (ioctl(fd, FBIOPUT_SHOW_HIFB, &bShow) < 0)
  293.     {
  294.         SAMPLE_PRT("FBIOPUT_SHOW_HIFB failed!\n");
  295.         close(fd);
  296.         return HI_NULL;
  297.     }

  298.     if (HI_FAILURE == HI_MPI_SYS_MmzAlloc(&(stCanvasBuf.stCanvas.u32PhyAddr), ((void**)&pBuf),
  299.                                           NULL, NULL, maxW * maxH * 2))
  300.     {
  301.         SAMPLE_PRT("allocate memory (maxW*maxH*2 bytes) failed\n");
  302.         close(fd);
  303.         return HI_NULL;
  304.     }
  305.     stCanvasBuf.stCanvas.u32Height = maxH;
  306.     stCanvasBuf.stCanvas.u32Width = maxW;
  307.     stCanvasBuf.stCanvas.u32Pitch = maxW * 2;
  308.     stCanvasBuf.stCanvas.enFmt = HIFB_FMT_ARGB1555;
  309.     memset(pBuf, 0x00, stCanvasBuf.stCanvas.u32Pitch * stCanvasBuf.stCanvas.u32Height);

  310.     /*change bmp*/
  311.     if (HI_FAILURE == HI_MPI_SYS_MmzAlloc(&Phyaddr, ((void**)&pOSDRGB),
  312.                                           NULL, NULL, SAMPLE_IMAGE_WIDTH * SAMPLE_IMAGE_HEIGHT * 2))
  313.     {
  314.         SAMPLE_PRT("allocate memory  failed\n");
  315.         HI_MPI_SYS_MmzFree(stCanvasBuf.stCanvas.u32PhyAddr, pBuf);
  316.         close(fd);
  317.         return HI_NULL;
  318.     }
  319.         if(NULL != pOSDRGB){
  320.                 memset(pOSDRGB,0x0,SAMPLE_IMAGE_WIDTH * SAMPLE_IMAGE_HEIGHT * 2);
  321.         }
  322.     /*init osd menu*/
  323.     OSD_MENU_Init();

  324.         /*copy memeroy*/
  325.         memcpy(pBuf,pOSDRGB,maxW*maxH*2);

  326.         //stCanvasBuf.UpdateRect.x = 180;
  327.         //stCanvasBuf.UpdateRect.y = 180;
  328.         stCanvasBuf.UpdateRect.x = 0;
  329.         stCanvasBuf.UpdateRect.y = 0;
  330.         stCanvasBuf.UpdateRect.w = maxW;
  331.         stCanvasBuf.UpdateRect.h = maxH;
  332.         s32Ret = ioctl(fd, FBIO_REFRESH, &stCanvasBuf);
  333.         if (s32Ret < 0)
  334.         {
  335.             SAMPLE_PRT("REFRESH failed!\n");
  336.             HI_MPI_SYS_MmzFree(Phyaddr, pOSDRGB);
  337.             HI_MPI_SYS_MmzFree(stCanvasBuf.stCanvas.u32PhyAddr, pBuf);
  338.             close(fd);
  339.             return HI_NULL;
  340.         }
  341.        
  342.         printf("Enter any key to exit\n");
  343.         getchar();

  344.     HI_MPI_SYS_MmzFree(Phyaddr, pOSDRGB);
  345.     HI_MPI_SYS_MmzFree(stCanvasBuf.stCanvas.u32PhyAddr, pBuf);
  346.     close(fd);

  347.     return 0;;
  348. }

  349. /**********************************************
  350. *
  351. *  Name:        OSD_MENU_HandleSig
  352. *  Description:  ctrl + c / z
  353. *  Param:       
  354. *  Return:
  355. *
  356. *********************************************/
  357. HI_VOID OSD_MENU_HandleSig(HI_S32 signo)
  358. {
  359.     if (SIGINT == signo || SIGTERM == signo)
  360.     {
  361.                 //HI_MPI_SYS_MmzFree(Phyaddr, pOSDRGB);
  362.                 //HI_MPI_SYS_MmzFree(stCanvasBuf.stCanvas.u32PhyAddr, pBuf);
  363.                 //close(fd);
  364.         printf("\033[0;31mprogram exit abnormally!\033[0;39m\n");
  365.     }

  366.     exit(0);
  367. }
  368. /**********************************************
  369. *
  370. *  Name:        main
  371. *  Description:  Program execution entry
  372. *  Param:        int argc, char *argv[]
  373. *  Return: 0
  374. *
  375. *********************************************/
  376. int main ( int argc, char *argv[] )
  377. {
  378.         char ch;
  379.         HI_S32 s32Ret = HI_SUCCESS;

  380.         signal(SIGINT,OSD_MENU_HandleSig);
  381.         signal(SIGTERM,OSD_MENU_HandleSig);
  382. /*       
  383.         s32Ret = OSD_MENU_StartVoDev();
  384.         if(HI_SUCCESS != s32Ret){
  385.                 printf("start vo device failed\n");
  386.                 return -1;
  387.         }
  388. */
  389.         OSD_MENU_HIFB_Refresh();
  390. start:
  391.         printf("Enter 'q' exit!\n");
  392.         ch = (char)getchar();
  393.         getchar();
  394.         if(ch != 'q')
  395.                 goto start;

  396.         return 0;
  397. }/*End of Main*/
复制代码


//还有几个疑问:
1.在 函数DrawOSD(unsigned char *buf, unsigned short *hzLib,int stride,int nColor) 内,为何要用for循环16次?
2.这种内存拷贝的方式,能不能直接利用freetype生成位图后拷贝呢?

//////目前的效果图如下:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
 楼主| 发表于 2016-6-20 16:58:28 | 显示全部楼层
本帖最后由 ngswfx 于 2016-6-20 19:12 编辑
love_lin 发表于 2016-6-20 11:21
至于上周六我提出来的背景半透明,以后我会慢慢研究。然而我就是连续调用你的几个函数接口,还是没办法显示 ...


1、字体的寬高,16*16的,要一个点一个点的处理 。
2、只要大小匹配当然可以。

/////////////////你现在的问题主要是编译环境的问题。

我这边用的eclipse 交叉编译的,配置的C++环境  配置的GBK环境,这个估计是关键点。也就是说.c文件里面的中文字,本身被保存成什么格式了?

 楼主| 发表于 2016-6-20 20:23:11 | 显示全部楼层
本帖最后由 ngswfx 于 2016-6-20 20:43 编辑
love_lin 发表于 2016-6-20 11:21
至于上周六我提出来的背景半透明,以后我会慢慢研究。然而我就是连续调用你的几个函数接口,还是没办法显示 ...


解决方法如下:

//如果想让HZ16Lib.c被编译,直接放到sample 目录下的common目录就可以了。
//也可以弄成.h,直接被sample_hifb.c 里面include,这个不是问题的关键。

//你现在那个乱码,是由于sample_hifb.c是UTF-8格式,而GCC默认也是UTF-8格式。这个字库,估计不能在这种环境下用,具体原因我也搞不懂,中文字体显示问题牵扯东西很多,我也搞不明白。
/////////////////解决方法:
1、使用geidt打开sample_hifb.c文件,删除所有中文注释,先屏蔽掉ShowOSD_DEC_BOX_MX这几行代码,然后将文件通过另存为,将文件保存为GBK格式,注意,可能需要手动添加GBK支持。
2、成功保存为GBK格式后,再次打开这个文件,确认一下是不是GBK格式,(再次选择另存为,可以看出来),如果已经是GBK格式的源文件了,尝试开启ShowOSD_DEC_BOX_MX这几行代码,确认里面不是乱码。保存文件sample_hifb.c。
3、修改makefile ,编译选项加入-finput-charset=GBK                //指定源文件的格式是GBK
4、make


附件中,是已经调整过的源码,不过我把2个缓冲,直接弄成一个了,刷新时,可能会看到绘制过程,这个不是问题的关键。

//3520D上运行通过

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
发表于 2016-6-21 08:24:39 | 显示全部楼层
本帖最后由 love_lin 于 2016-6-21 08:26 编辑
ngswfx 发表于 2016-6-20 20:23
解决方法如下:

//如果想让HZ16Lib.c被编译,直接放到sample 目录下的common目录就可以了。


真是厉害,谢谢指导,我刚试了一下,目前能正常显示了,效果图如下(空格不行)。
目前只能修改字体的颜色和字间距,那能修改字体和字体的大小吗?它们是由什么决定的?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
 楼主| 发表于 2016-6-21 16:31:14 | 显示全部楼层
love_lin 发表于 2016-6-21 08:24
真是厉害,谢谢指导,我刚试了一下,目前能正常显示了,效果图如下(空格不行)。
目前只能修改字体的 ...

字体的大小没法改,只能通过数据拷贝的方式,进行倍数放大,但由于字库本事是16的,所以放大效果并不好
放大2倍基本还能接受,多了就不行了。你就把16*16,水平和垂直都按照点重复一遍就是放大2倍了。
//////////如果项目有需求,可以用32大小的字库,网上应该有,效果会好一些。

/////////空格等的处理手段,应该也不难,再对某个字符查寻的时候,如果发现是空格等不支持的字符。这个字符所在位置,全部都赋值为背景色,这样就相当于空格了。

///////咱们现在搞的是比较基础的、比较底层的叠加,很多都需要靠自己根据原理去思考解决问题的方法。
发表于 2016-6-22 18:47:12 | 显示全部楼层
谢谢您的帮助,目前实现的OSD菜单还算比较满意,唯一不足的是还没做背景,这个估计还得研究一阵子。
至于字体确实太小了,在网上也没找到 ,不知道您有没有32*32的,或24*24的。
效果图如下:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
 楼主| 发表于 2016-6-22 18:59:29 | 显示全部楼层
love_lin 发表于 2016-6-22 18:47
谢谢您的帮助,目前实现的OSD菜单还算比较满意,唯一不足的是还没做背景,这个估计还得研究一阵子。
至于 ...

不错,有点意思了
 楼主| 发表于 2016-6-22 19:00:38 | 显示全部楼层
本帖最后由 ngswfx 于 2016-6-22 19:07 编辑
ngswfx 发表于 2016-6-22 18:59
不错,有点意思了


///////////关键部分代码  附件中有字库,不过字库就大一些了,不知道打包到文件会压缩成怎样。

//下面的代码我没试过,可能需要自己根据字库修改。下面的代码肯定不是1555的,应该是YUV 中针对Y这部分
//32*32 hzk
unsigned long __stdcall        ShowOSD32Ex(unsigned char *pBase, char *pStr, unsigned short x, unsigned short y, unsigned short space, unsigned char Lum, int width, int height, int stride)
{
        Int8 q=3, w, asc=0,*p=(Int8 *)pStr;
        UInt8 *pHZLib=0;
        UInt32 nChar=0,wd=0,nOffset=0,nSize, l, r;
        float fsize = 0,fwd = 0;       
        Int8        *pp = p, num=0;       
        x = UCLIPI(x, width-48);
        y = UCLIPI(y, height-24);
        pBase += stride*y*2+x*2;
        while (*p) {               
                pp = p;
                q = *p&0x80?(*p++)-161:2; // Get qu code
                w=((*p++)&0x7f)-33; // Get wei code               
                if ((nOffset = q*94+w) >= g_real_HZ16_count)
                        continue;
                //32*32
                pHZLib = (HZ32Lib+(nOffset<<7));               
                if (q<10) {
                        l = UBYTESEL(HZ16_Space[nOffset],1)*2;
                        r = UBYTESEL(HZ16_Space[nOffset],0)*2;
                        nSize = HZ32LIB_ZISE-(l+r);//+space;
                        fsize = 20.2;
                }
                else {
                        nSize = HZ32LIB_ZISE+space;
                        l = r = 0;
                        fsize = 40.4;
                }               
                if (x+(int)fwd+(int)fsize+2>width)
                        break;               
                // Draw here
                DrawOSD32(pBase+wd+nChar*(16-r-l), (unsigned int *)pHZLib,Lum,64,stride);
                nChar++;
                wd += nSize;
                fwd += fsize;
        }       
        return nChar;
}
void DrawOSD32(unsigned char *buf, unsigned int *hzLib, char lum, char bklum, int stride)
{
        static unsigned char fontlum[] = {64,192};
        int i, font;
        int        lumi,chroma_u,chroma_v;
        int *p1 = (int *) buf+(stride<<4);
        float mult_f = lum?0.20:1;
        float mult_b = 1 - mult_f;

        int avglum = (buf[0] + buf[2] + buf[4] + buf[6] + buf[8] +
                buf[10] + buf[12] + buf[14] + buf[16] + buf[18] + buf[20] +
                buf[22] + buf[24] + buf[26] + buf[28] + buf[30] +buf[32] +
                buf[34] + buf[36] + buf[38] + buf[40] + buf[42] +buf[44] +
                buf[46] + buf[48] + buf[50] +buf[52] +buf[54] +buf[56] +
                buf[58] + buf[60] +buf[62])/32;

        if(avglum>135)
                lumi = 0x1;
        else
                lumi = 0xff;

        //lumi = 0xff;
        chroma_u = 0x80;
        chroma_v = 0x80;

        for (i=0; i<32; i++) {
                font = *hzLib ++;
/*
                buf[0]   = MUX(font&0x0080, lumi, buf[0] );
                buf[2]   = MUX(font&0x0040, lumi, buf[2] );
                buf[4]   = MUX(font&0x0020, lumi, buf[4] );
                buf[6]   = MUX(font&0x0010, lumi, buf[6] );
                buf[8]   = MUX(font&0x0008, lumi, buf[8] );
                buf[10]   = MUX(font&0x0004, lumi,buf[10]);
                buf[12]   = MUX(font&0x0002, lumi,buf[12]);
                buf[14]   = MUX(font&0x0001, lumi,buf[14]);
                buf[16]   = MUX(font&0x8000, lumi,buf[16]);
                buf[18]   = MUX(font&0x4000, lumi,buf[18]);
                buf[20] = MUX(font&0x2000, lumi,  buf[20]);
                buf[22] = MUX(font&0x1000, lumi,  buf[22]);
                buf[24] = MUX(font&0x0800, lumi,  buf[24]);
                buf[26] = MUX(font&0x0400, lumi,  buf[26]);
                buf[28] = MUX(font&0x0200, lumi,  buf[28]);
                buf[30] = MUX(font&0x0100, lumi,  buf[30]);
*/
                buf[0]   = (unsigned char)(MUX(font&0x0080, lumi*mult_f+buf[0]*mult_b, buf[0] ));
                buf[2]   = (unsigned char)(MUX(font&0x0040, lumi*mult_f+buf[2]*mult_b, buf[2] ));
                buf[4]   = (unsigned char)(MUX(font&0x0020, lumi*mult_f+buf[4]*mult_b, buf[4] ));
                buf[6]   = (unsigned char)(MUX(font&0x0010, lumi*mult_f+buf[6]*mult_b, buf[6] ));
                buf[8]   = (unsigned char)(MUX(font&0x0008, lumi*mult_f+buf[8]*mult_b, buf[8] ));
                buf[10]   = (unsigned char)(MUX(font&0x0004, lumi*mult_f+buf[10]*mult_b,buf[10]));
                buf[12]   = (unsigned char)(MUX(font&0x0002, lumi*mult_f+buf[12]*mult_b,buf[12]));
                buf[14]   = (unsigned char)(MUX(font&0x0001, lumi*mult_f+buf[14]*mult_b,buf[14]));
                buf[16]   = (unsigned char)(MUX(font&0x8000, lumi*mult_f+buf[16]*mult_b,buf[16]));
                buf[18]   = (unsigned char)(MUX(font&0x4000, lumi*mult_f+buf[18]*mult_b,buf[18]));
                buf[20] = (unsigned char)(MUX(font&0x2000, lumi*mult_f+buf[20]*mult_b,  buf[20]));
                buf[22] = (unsigned char)(MUX(font&0x1000, lumi*mult_f+buf[22]*mult_b,  buf[22]));
                buf[24] = (unsigned char)(MUX(font&0x0800, lumi*mult_f+buf[24]*mult_b,  buf[24]));
                buf[26] = (unsigned char)(MUX(font&0x0400, lumi*mult_f+buf[26]*mult_b,  buf[26]));
                buf[28] = (unsigned char)(MUX(font&0x0200, lumi*mult_f+buf[28]*mult_b,  buf[28]));
                buf[30] = (unsigned char)(MUX(font&0x0100, lumi*mult_f+buf[30]*mult_b,  buf[30]));
               
                buf[32] = (unsigned char)(MUX(font&0x800000,lumi*mult_f+buf[32]*mult_b,buf[32]));
                buf[34] = (unsigned char)(MUX(font&0x400000,lumi*mult_f+buf[34]*mult_b, buf[34]));
                buf[36] = (unsigned char)(MUX(font&0x200000, lumi*mult_f+buf[36]*mult_b, buf[36] ));
                buf[38] = (unsigned char)(MUX(font&0x100000, lumi*mult_f+buf[38]*mult_b, buf[38] ));
                buf[40] = (unsigned char)(MUX(font&0x080000, lumi*mult_f+buf[40]*mult_b, buf[40] ));
                buf[42] = (unsigned char)(MUX(font&0x040000, lumi*mult_f+buf[42]*mult_b,buf[42]));
                buf[44] = (unsigned char)(MUX(font&0x020000, lumi*mult_f+buf[44]*mult_b,buf[44]));
                buf[46] = (unsigned char)(MUX(font&0x010000, lumi*mult_f+buf[46]*mult_b,buf[46]));
                buf[48] = (unsigned char)(MUX(font&0x80000000, lumi*mult_f+buf[48]*mult_b,buf[48]));
                buf[50] = (unsigned char)(MUX(font&0x40000000, lumi*mult_f+buf[50]*mult_b,buf[50]));
                buf[52] = (unsigned char)(MUX(font&0x20000000, lumi*mult_f+buf[52]*mult_b,buf[52]));
                buf[54] = (unsigned char)(MUX(font&0x10000000, lumi*mult_f+buf[54]*mult_b,buf[54]));
                buf[56] = (unsigned char)(MUX(font&0x08000000, lumi*mult_f+buf[56]*mult_b,buf[56]));
                buf[58] = (unsigned char)(MUX(font&0x04000000, lumi*mult_f+buf[58]*mult_b,buf[58]));
                buf[60] = (unsigned char)(MUX(font&0x02000000, lumi*mult_f+buf[60]*mult_b,buf[60]));
                buf[62] = (unsigned char)(MUX(font&0x01000000, lumi*mult_f+buf[62]*mult_b,buf[62]));               
               
                buf[1]   = (unsigned char)(MUX(font&0x0080, chroma_u, buf[1] ));
                buf[3]   = (unsigned char)(MUX(font&0x0040, chroma_v, buf[3] ));
                buf[5]   = (unsigned char)(MUX(font&0x0020, chroma_u, buf[5] ));
                buf[7]   = (unsigned char)(MUX(font&0x0010, chroma_v, buf[7] ));
                buf[9]   = (unsigned char)(MUX(font&0x0008, chroma_u, buf[9] ));
                buf[11]   = (unsigned char)(MUX(font&0x0004, chroma_v,buf[11]));
                buf[13]   = (unsigned char)(MUX(font&0x0002, chroma_u,buf[13]));
                buf[15]   = (unsigned char)(MUX(font&0x0001, chroma_v,buf[15]));
                buf[17]   = (unsigned char)(MUX(font&0x8000, chroma_u,buf[17]));
                buf[19]   = (unsigned char)(MUX(font&0x4000, chroma_v,buf[19]));
                buf[21] = (unsigned char)(MUX(font&0x2000, chroma_u,  buf[21]));
                buf[23] = (unsigned char)(MUX(font&0x1000, chroma_v,  buf[23]));
                buf[25] = (unsigned char)(MUX(font&0x0800, chroma_u,  buf[25]));
                buf[27] = (unsigned char)(MUX(font&0x0400, chroma_v,  buf[27]));
                buf[29] = (unsigned char)(MUX(font&0x0200, chroma_u,  buf[29]));
                buf[31] = (unsigned char)(MUX(font&0x0100, chroma_v,  buf[31]));

                buf[33]   = (unsigned char)(MUX(font&0x800000, chroma_u, buf[33] ));
                buf[35]   = (unsigned char)(MUX(font&0x400000, chroma_v, buf[35] ));
                buf[37]   = (unsigned char)(MUX(font&0x200000, chroma_u, buf[37] ));
                buf[39]   = (unsigned char)(MUX(font&0x100000, chroma_v, buf[39] ));
                buf[41]   = (unsigned char)(MUX(font&0x080000, chroma_u, buf[41] ));
                buf[43]   = (unsigned char)(MUX(font&0x040000, chroma_v,buf[43]));
                buf[45]   = (unsigned char)(MUX(font&0x020000, chroma_u,buf[45]));
                buf[47]   = (unsigned char)(MUX(font&0x010000, chroma_v,buf[47]));
                buf[49]   = (unsigned char)(MUX(font&0x80000000, chroma_u,buf[49]));
                buf[51]   = (unsigned char)(MUX(font&0x40000000, chroma_v,buf[51]));
                buf[53] = (unsigned char)(MUX(font&0x20000000, chroma_u,  buf[53]));
                buf[55] = (unsigned char)(MUX(font&0x10000000, chroma_v,  buf[55]));
                buf[57] = (unsigned char)(MUX(font&0x08000000, chroma_u,  buf[57]));
                buf[59] = (unsigned char)(MUX(font&0x04000000, chroma_v,  buf[59]));
                buf[61] = (unsigned char)(MUX(font&0x02000000, chroma_u,  buf[61]));
                buf[63] = (unsigned char)(MUX(font&0x01000000, chroma_v,  buf[63]));
               
                buf += stride*2;
        }
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
发表于 2016-6-23 10:24:49 | 显示全部楼层
非常感谢,谢谢分享。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|手机版|小黑屋|易百纳 ( 苏ICP备14036084 )

GMT+8, 2017-6-24 21:47 , Processed in 0.158715 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表