型号:A191-EB-RV1126 摄像头:gc2053

参考了以下大佬的博文
https://blog.csdn.net/tang200710312333/article/details/105821179
https://blog.csdn.net/u010034969/article/details/112236885
但是都是海思平台的实现方法和RK平台还是多少有点区别

过程就是把用sdl生成bmp图转为位图然后叠加到对应的数据上面去

最主要的地方是 sdl默认生成的是16位 rgb565 格式的图,而rv1126 osd叠加的图只能是32位ARGB888格式的
所以要把对应的图转一下格式才可以显示,因此就需要一位一位像素的处理

安装freetype sdl sdl_tffd 的库文件

首先你需要把以上对应的库按顺序安装好,网上教程也很多,这里不细说,记得编译的时候用RV1126交叉编译工具链,把编译后生成的库文件和头文件都要放到开发板上去,并且把对应的路径也添加上去。安装参考博文如下:
https://blog.csdn.net/whereisdog/article/details/82769222

也可以参考下面这个博文,编写自己的CMake编译工程。(可跳过)
https://blog.csdn.net/m0_50887633/article/details/134446233?spm=1001.2014.3001.5501

SDL API简介

https://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlcolor.html

参考rkmedia_venc_osd_test.c

下面贴上核心代码

static void *GetOSDBuffer(void *arg) {
  
    time_t now;
    struct tm *ptm;
    char timestr[100] = {0}; 

// 从左上角开始算(bitmap_PosX, bitmap_PosY),(0,0)
// bitmap的长宽要保持 16的倍数的比例
  int bitmap_width = 0;
  int bitmap_height = 0;
  int bitmap_PosX = 0;
  int bitmap_PosY = 0;
  int wxh_size = 0;

    RK_MPI_VENC_RGN_Init(0, NULL);

  while (!quit) {

//bitmap的长宽要保持 16的倍数的比例
    bitmap_width = 992;
    bitmap_height = 144;
    bitmap_PosX = 0;
    bitmap_PosY = 0;

    if (bitmap_width < 64)
      bitmap_width = 64;
    if (bitmap_height < 64)
      bitmap_height = 64;



    //像素结构
    SDL_PixelFormat *fmt;
    //字体结构
    TTF_Font *font;  
    //图面结构
    //把文字SDL_Surface 输出到屏幕显示,如果不需它,必须释放它
    //文字表面和其他表面一样,可以传输到显示表面显示。
    SDL_Surface *text, *temp;  

    //创建时间
    time(&now);
    ptm = localtime(&now);
    snprintf(timestr,100,"时间%d-%02d-%02d %02d:%02d:%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);

     if (TTF_Init() < 0 ) 
    {  
        fprintf(stderr, "Couldn't initialize TTF: %s\n",SDL_GetError());  
        SDL_Quit();
    }  
//打开字库,设字体为80号
    font = TTF_OpenFont(FONT_PATH, 80);  //FONT_PATH 对应的.ttf文件路径,自行下载
    if ( font == NULL ) 
    {  
        fprintf(stderr, "Couldn't load %d pt font from %s: %s\n",18,"ptsize", SDL_GetError());  
    }  
//设置字体颜色
    SDL_Color forecol = { 0x00,0x00, 0x00}; //3个参数分别代表rgb  
//SDL显示中文  
    text = TTF_RenderUTF8_Solid(font,timestr, forecol);
//定义格式    
    fmt = (SDL_PixelFormat*)malloc(sizeof(SDL_PixelFormat));
    memset(fmt,0,sizeof(SDL_PixelFormat));
    fmt->BitsPerPixel = 16;  //每像素位数
    fmt->BytesPerPixel = 2; //每像素字节数
    fmt->colorkey = 0xffffffff;
    fmt->alpha = 0xff;  //透明度 0<=alpha<=255
 //将现有表面复制到一个新的表面,该表面针对指定像素格式的表面进行了优化。
 //默认 RGB565格式
    temp = SDL_ConvertSurface(text,fmt,0);
  
  BITMAP_S stBitmap;
  //将渲染后的Surface转换成Bitmap
  // 转成ARGB8888格式
	MySample_SurfaceWord_ToBMP(temp,&stBitmap,forecol);  

//把文字SDL_Surface释放
    SDL_FreeSurface(text);  
    SDL_FreeSurface(temp);
//关闭TTF_Font字体    
    TTF_CloseFont(font);  
//释放TTF库    
    TTF_Quit(); 

//释放 fmt        
    free(fmt);
    fmt = NULL;
//重置时间字符串
  	memset(timestr,0,100);

    OSD_REGION_INFO_S RngInfo;

    RngInfo.enRegionId = 5;
    RngInfo.u32PosX = bitmap_PosX;
    RngInfo.u32PosY = bitmap_PosY;
    RngInfo.u32Width = bitmap_width;
    RngInfo.u32Height = bitmap_height;
    RngInfo.u8Enable = 1;
    RngInfo.u8Inverse = 0;
    printf("# ENABLE RGN enRegionId[%d]: < u32PosX:%d,u32PosY:%d,u32Width:%d,u32Height:%d> for 100ms...\n", 
           RngInfo.enRegionId, RngInfo.u32PosX, RngInfo.u32PosY,
           RngInfo.u32Width, RngInfo.u32Height);

    int ret = RK_MPI_VENC_RGN_SetBitMap(0, &RngInfo, &stBitmap);  //
    if (ret) {
      printf("ERROR: set rgn stBitmap(enable) failed! ret=%d\n", ret);
      if (stBitmap.pData)
        free(stBitmap.pData);
      break;
    }

    // free stBitmap
    free(stBitmap.pData);
    stBitmap.pData = NULL;


    // usleep(100000);
    usleep(1000000);
  } //while

}
/将渲染后的Surface转换成Bitmap
 void MySample_SurfaceWord_ToBMP(SDL_Surface *surface,BITMAP_S *stBitmap,SDL_Color fntcol)
{
  unsigned short words_color = ((fntcol.r >> 3) << 11) + ((fntcol.g >> 2) << 5) + (fntcol.b >> 3);
  unsigned short bck_color = 0xffff - words_color;
  stBitmap->u32Height = (surface->h); //BITMAP 的宽高向上2对齐
	stBitmap->u32Width = (surface->w);
	stBitmap->pData = malloc(4*(stBitmap->u32Height)*(stBitmap->u32Width)); //申请空间,ARGB8888=>4Byte/Pixel,总大小为4*w*h
	memset(stBitmap->pData,0,4*(stBitmap->u32Height)*(stBitmap->u32Width));
	int i,j;
	int w = surface->w;
	int h = surface->h;

	for (i = 0; i < h; ++i)
	{
		RK_U32 *p_dst = (RK_U32*)stBitmap->pData;
		RK_U16 *p_src = (RK_U16*)surface->pixels;
	    int dis_pos = 0;
	    if(w % 2 != 0)
	    	dis_pos = i;     //处理w为奇数的情况
		for(j=0;j<w;j++)
		{
			int a,r, g , b;
			r = (p_src[i*w+dis_pos+j] & 0xF800) >> 8;   //原图像是RGB565,RGB各分量提取
			g = (p_src[i*w+dis_pos+j] & 0x07e0) >> 3;
			b = (p_src[i*w+dis_pos+j] & 0x001f) << 3;
			
      //一致则A位设置为0,透明
      if (bck_color == p_src[i*w+dis_pos+j])
      a = 0x00;
      else a = 0xff;

			p_dst[i*stBitmap->u32Width+j] = (a << 24) | (r << 16) | (g << 8) | b; //转换成ARGB888
		}
	}
	stBitmap->enPixelFormat = PIXEL_FORMAT_ARGB_8888;
}

最终效果图
![在这里插入图片描述](https://img-blog.csdnimg.cn/ae9d804db23544b5ab4d5695b7474095.png
记录下自己的学习过程,希望能对你有帮助

GitHub 加速计划 / sd / SDL
17
0
下载
Simple Directmedia Layer
最近提交(Master分支:6 个月前 )
ca29304c - 1 天前
f67c6446 - 1 天前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐