RV1126学习笔记 OSD叠加中文字体时间sdl sdl_tff

型号: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
记录下自己的学习过程,希望能对你有帮助

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
要在Linux平台上使用SDL字体,需要安装相应的开发包。一般来说,可以使用以下命令安装: ``` sudo apt-get install libsdl2-dev libsdl2-ttf-dev libfreetype6-dev ``` 接下来,可以使用SDL_ttf库来加载和渲染TrueType字体。以下是一个简单的示例程序: ``` c #include <SDL2/SDL.h> #include <SDL2/SDL_ttf.h> #include <stdio.h> int main(int argc, char* argv[]) { SDL_Window* window = NULL; SDL_Renderer* renderer = NULL; TTF_Font* font = NULL; SDL_Surface* surface = NULL; SDL_Texture* texture = NULL; SDL_Rect rect; SDL_Init(SDL_INIT_VIDEO); TTF_Init(); window = SDL_CreateWindow("SDL Font Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN); renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); font = TTF_OpenFont("arial.ttf", 24); if (!font) { printf("TTF_OpenFont error: %s\n", TTF_GetError()); return 1; } surface = TTF_RenderText_Solid(font, "Hello, world!", (SDL_Color){255, 255, 255, 255}); if (!surface) { printf("TTF_RenderText_Solid error: %s\n", TTF_GetError()); return 1; } texture = SDL_CreateTextureFromSurface(renderer, surface); rect.x = 0; rect.y = 0; rect.w = surface->w; rect.h = surface->h; SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texture, NULL, &rect); SDL_RenderPresent(renderer); SDL_Delay(3000); SDL_DestroyTexture(texture); SDL_FreeSurface(surface); TTF_CloseFont(font); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); TTF_Quit(); SDL_Quit(); return 0; } ``` 在这个示例程序中,我们使用TTF_OpenFont函数加载Arial字体,并使用TTF_RenderText_Solid函数渲染“Hello, world!”文本。SDL_Color结构体用于指定字体颜色。最后,我们将渲染好的字体纹理复制到渲染器上,并调用SDL_RenderPresent函数显示结果。 在海思平台中,使用SDLSDL_ttf库需要进行交叉编译。具体步骤可以参考海思提供的开发文档。在渲染字体时,可以使用SDL_SetTextureColorMod函数设置纹理的颜色模式,例如: ``` c SDL_SetTextureColorMod(texture, 255, 0, 0); // 将纹理颜色设置为红色 ``` 这样可以实现字体颜色的设定。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值