大连网站建设外包公司商丘网络第一媒体
大连网站建设外包公司,商丘网络第一媒体,电脑当网站空间,做海报用的图片网站在流媒体项目中字幕显示是不可或缺的一环#xff0c;一般会有字幕流在视频播放过程中进行显示#xff1b;不过还有很多情况是从头到尾只在视频的某个区域显示某些文字#xff0c;例如某个电视台的log#xff1b;这种也称为字幕#xff0c;如果想要将这些字符串显示到视频一般会有字幕流在视频播放过程中进行显示不过还有很多情况是从头到尾只在视频的某个区域显示某些文字例如某个电视台的log这种也称为字幕如果想要将这些字符串显示到视频需要将这些字符串做成位图进行显示无法直接显示freetype开源库就是将字符转化为位图的工具。 做了几个freetype的项目之后总结的几个难点
1.utf8或者gb2312等中文如何生成位图 画布和freetype是无法处理中文编码的像GB2312或UTF8等中文编码需要转换成unicode编码才能够被处理显示字符串的编码转换可以使用iconv库进行编码转换想要了解更多iconv库的详细情况关注我后期持续更新。
2.生成的位图如何显示到画布上核心点最难点 首先明确一点freetype只是将字符做成位图的工具不涉及位图在画布显示相关的配置具体如何将位图显示到LCD(嵌入式称为画布) 利用c/c的话术来说就是将保存位图的缓存内容拷贝到画布的缓存上即可。但是不仅仅是简单的字符拷贝在拷贝的过程中还要考虑到LCD的像素格式RGB888RGB555等不同的像素格式单个像素所占的内存大小是不一样的就导致拷贝时的内存偏移是不同的下面代码进行跟明确的解释
//这里LCD的像素格式为ARGB8888,即一个像素占四个字节A透明度(8bit)R红色(8bit)G绿色(8bit)B:蓝色(8bit)
void Manage::lcd_put_pixel(int x, int y, unsigned int pixel, unsigned int color)
{/**Get_Canvas_Addr()画布的地址*(32 / 8):一个像素占多少字节*Get_Stride()垂直步长和像素格式有关假如画布的分辨率为1920*1080像素格式为ARGB8888则垂直步长为1920*4* 很好理解画布水平有1920个像素点每个像素点占四个字节*/unsigned char *pen_8 (Get_Canvas_Addr() x * (32 / 8) y * Get_Stride());//画布显示位置在画布缓存中的地址偏移unsigned int *pen_16;unsigned int red 0, green 0xff, blue 0;pen_16 (unsigned int *)pen_8;//pixel:代表像素点的值if (pixel ! 0){ //一个像素由RGB组成而像素格式占四个字节所以将unsigned char类型的缓存转换成unsigned int类型进行赋值代表整个像素点pixel color;}else{//没有像素点说明是空白区域以白色填充*pen_16 0x0000;}//将像素值拷贝到画布*pen_16 pixel;
}如果对于画布的坐标偏移很难理解参考下下图 其中坐标点就是位图想要在画布上显示的坐标点颜色相同的四个方块代表一个像素点一个方块代表一个字节则坐标点在画布的缓存中的地址位置为y*(1920*4)x*4; 这样就很清楚明了了吧 这个模块就是将生成好的位图数据显示到LCD画布的过程在实际的项目开发中画布的坐标画布的分辨率画布的像素格式位图的坐标位图的各种参数都是非常重要的考虑项想要了解更多关注我后续持续更新
3.LCD坐标和笛卡尔坐标在实际项目中如何应用 lcd坐标就是LCD在做图像显示时的坐标以左上角为原点y轴与笛卡尔坐标相反向下为正x轴与笛卡尔坐标一样 笛卡尔坐标就是我们上学时学到坐标轴 为什么要说这两个坐标的因为如果坐标与freetype接口相关的话就会涉及到笛卡尔坐标因为freetype内部使用的时笛卡尔坐标需要与LCD坐标进行转换。 具体分析图如下 在进行位图渲染时freetype是按照红点为原点进行坐标设置的而LCD(画布)是按照绿色原点进行设置的因此如果坐标使用freetype进行设置那么y坐标要使用LCD的高减去想要的y值才是我们想要的坐标 如上图想要让位图显示在LCD(100,100)的坐标处但是使用freetype时y坐标就不能设置为100而要设置为h-100x都是一样的不用考虑x的转换。 有如下代码
//该代码是从实际项目中摘录删去了无用代码导致可能无法编译仅表示位图生成过程
int Manage::FreeType_Generate_Bitmap(uint32_t h, uint32_t w, std::string color)
{FT_Library library;FT_Face face;FT_GlyphSlot slot;FT_Error error;unsigned int co 0;// 初始化 FreeType 库error FT_Init_FreeType(library);if (error){printf(Failed to initialize FreeType library\n);return 1;}// 加载字体文件error FT_New_Face(library, /mmc_data/msyh.ttf, 0, face);if (error FT_Err_Unknown_File_Format){printf(Unsupported font file format\n);return 1;}else if (error){printf(Failed to load font file\n);return 1;}slot face-glyph;FT_Select_Charmap(face, FT_ENCODING_UNICODE);// // 设置字体大小,后面两个参数是长宽如果其中一个为0则默认与另一个参数相同FT_Set_Pixel_Sizes(face, 0, 48);// 只使用灰度位图FT_Render_Mode render_mode FT_RENDER_MODE_NORMAL;// 设置字符串const char *text hello;// 计算字符串在画布的中间位置int string_width 0;int string_height 0;//计算将整个字符串转换为位图后位图的总长度和总高度for (int i 0; i strlen(text); i){FT_Load_Char(face, text[i], FT_LOAD_RENDER);// string_width face-glyph-bitmap.width;//计算总长度时要使用水平步长(face-glyph-advance.x),不要使用字符位图宽度(face-glyph-bitmap.width),因为位图是按照//水平步长或者垂直步长进行偏移的两者的区别请参考我的文章string_width (face-glyph-advance.x 6);if (face-glyph-bitmap.rows string_height){string_height face-glyph-bitmap.rows;}}// 逐字符渲染并绘制到位图//pen_x,pen_y就是我们想要设置的LCD坐标int pen_x (w - string_width) / 2;int pen_y string_height - slot-bitmap_top;FT_Vector pen;//使用freetype时要乘以64因为freetype内部是1/64像素pen.x pen_x * 64;pen.y pen_y * 64;printf(pen_x : %d, pen_y : %d, top : %d\n, pen_x, pen_y, slot-bitmap_top);co Get_Int_Color(color);for (int i 0; i strlen(text); i){//使用FT_Set_Transform接口将pen_x,pen_y转化为freetype坐标FT_Set_Transform(face, 0, pen);error FT_Load_Char(face, text[i], FT_LOAD_RENDER);if (error){printf(Failed to load glyph\n);continue;}//FT_Set_Transform转化之后x坐标为slot-bitmap_lefty坐标为slot-bitmap_topint x slot-bitmap_left; // 字形位图的左边界偏移int y h - slot-bitmap_top; // 字形位图的上边界偏移,这就是上面说到的坐标转换再将freetype笛卡尔坐标转换为LCD坐标FT_Int x_max x slot-bitmap.width;FT_Int y_max y slot-bitmap.rows;//下面就是将位图渲染到LCD的过程参考上面第二小节for (int i x, p 0; i x_max; i, p){for (int j y, q 0; j y_max; j, q){if (i 0 || j 0 || i w || j h)continue;lcd_put_pixel(i, j, slot-bitmap.buffer[q * slot-bitmap.width p], co);}}pen.x slot-advance.x;// pen.y slot-advance.y;}// 释放资源FT_Done_Face(face);FT_Done_FreeType(library);return 0;
} 当然如果你觉得坐标的相互转换很迷惑我这有一种方可可以只考虑LCD坐标不考虑笛卡尔坐标也就是坐标不经过freetype具体方法关注我后期会出一篇详解freetype及使用技巧的文章
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/88527.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!