首页 > 分享 > 【嵌入式】利用freetype字体库(绘制中文)

【嵌入式】利用freetype字体库(绘制中文)

终极目标:利用freetype开源字体库,实现在图片上书写一行字体大小变化的诗句(比如首字体增大)

目录 (一) 树莓派3b+freetype2.4.101. 下载2. 解压及配置3. 添加字体库4. 一个简单的Demo5.freetype2+opencv3在图片上绘制中文 (二) VS2017+freetype2.9.11. 下载2. 解压及配置3. 一个简单的Demo

(一) 树莓派3b+freetype2.4.10

1. 下载

我是在PC上下载好Linux版本,用teamviewer传到派上的;也可以直接在pi上下载。

官网链接:https://sourceforge.net/projects/freetype/files/freetype2/

注意:Linux系统下需要的版本为:freetype-2.*.*.tar.br2;版本自选。
在这里插入图片描述
我选择的是2.4.10,可任选
在这里插入图片描述
用teamviewer直接传文件到/home/pi目录下:
在这里插入图片描述

2. 解压及配置

进入命令模式解压(对应版本):

tar -xjf freetype-2.4.10.tar.bz2 1

在这里插入图片描述

进入安装包:

cd freetype-2.4.10/ 1

在这里插入图片描述

配置:

./configure 1

在这里插入图片描述
配置完成如图:
在这里插入图片描述

编译:(需要几分钟时间)

make 1

在这里插入图片描述
编译完成如图:
在这里插入图片描述

直接将库安装到根目录/usr/local/里,所以需要加sudo:

sudo make install 1

在这里插入图片描述
完成如图:
在这里插入图片描述

3. 添加字体库

查看本地字体库目录

树莓派:/usr/share/fonts Windows:C:WindowsFonts 12

经查看,我的pi目录下没有宋体(simhei.ttf)、(simsun.ttc)的字体文件,我从pc上传了一份过去,注意填写的接收地址。
在这里插入图片描述

4. 一个简单的Demo

新建文件夹freetype_test将刚才传输的simsun.ttc字体库样式复制到freetype_test文件夹下在freetype_test文件夹下创建 test.cpp编写代码(这里的源码我是参照网上的,先直接拖进去试试水)

#include <stdio.h> #include <string.h> #include <math.h> #include <ft2build.h> #include FT_FREETYPE_H #define WIDTH 80 #define HEIGHT 80 /* origin is the upper left corner */ unsigned char image[HEIGHT][WIDTH]; /* Replace this function with something useful. */ void draw_bitmap( FT_Bitmap* bitmap, FT_Int x, FT_Int y) { FT_Int i, j, p, q; FT_Int x_max = x + bitmap->width; FT_Int y_max = y + bitmap->rows; for ( i = x, p = 0; i < x_max; i++, p++ ) { for ( j = y, q = 0; j < y_max; j++, q++ ) { if ( i < 0 || j < 0 || i >= WIDTH || j >= HEIGHT ) continue; image[j][i] |= bitmap->buffer[q * bitmap->width + p]; } } } void show_image( void ) { int i, j; for ( i = 0; i < HEIGHT; i++ ) { for ( j = 0; j < WIDTH; j++ ) putchar( image[i][j] == 0 ? ' ' : image[i][j] < 128 ? '+' : '*' ); putchar( 'n' ); } } int main( int argc, char** argv ) { FT_Library library; FT_Face face; FT_GlyphSlot slot; FT_Matrix matrix; /* transformation matrix */ FT_Vector pen; /* untransformed origin */ FT_Error error; char* filename; char* text; double angle; int target_height; int n, num_chars; if ( argc != 3 ) { fprintf ( stderr, "usage: %s font sample-textn", argv[0] ); exit( 1 ); } filename = argv[1]; /* first argument */ text = argv[2]; /* second argument */ num_chars = strlen( text ); angle = ( 0.0 / 360 ) * 3.14159 * 2; /* use 25 degrees */ target_height = HEIGHT; error = FT_Init_FreeType( &library ); /* initialize library */ /* error handling omitted */ error = FT_New_Face( library, argv[1], 0, &face ); /* create face object */ /* error handling omitted */ #if 0 /* use 50pt at 100dpi */ error = FT_Set_Char_Size( face, 50 * 64, 0, 100, 0 ); /* set character size *//* pixels = 50 /72 * 100 = 69 */ #elseFT_Set_Pixel_Sizes(face, 24, 0); #endif /* error handling omitted */ slot = face->glyph; /* set up matrix */ matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L ); matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L ); matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L ); matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L ); /* the pen position in 26.6 cartesian space coordinates; */ /* start at (0,40) relative to the upper left corner */ pen.x = 0 * 64; pen.y = ( target_height - 40 ) * 64; for ( n = 0; n < num_chars; n++ ) { /* set transformation */ FT_Set_Transform( face, &matrix, &pen ); /* load glyph image into the slot (erase previous one) */ error = FT_Load_Char( face, text[n], FT_LOAD_RENDER ); if ( error ) continue; /* ignore errors */ /* now, draw to our target surface (convert position) */ draw_bitmap( &slot->bitmap, slot->bitmap_left, target_height - slot->bitmap_top ); /* increment pen position */ pen.x += slot->advance.x; pen.y += slot->advance.y; } show_image(); FT_Done_Face ( face ); FT_Done_FreeType( library ); return 0; }

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 保存回到命令行界面编译

gcc -o test test.cpp -I/usr/local/include/freetype2/ -lfreetype -lm 1 运行

./test ./simsun.ttc cungu 1

在这里插入图片描述

结果
在这里插入图片描述
配置成功!

5.freetype2+opencv3在图片上绘制中文

参考链接:http://lib.csdn.net/article/opencv/53782?tdsourcetag=s_pcqq_aiomsg

新建freetype_test文件夹,把simhei.ttf字体库和图片lena.jpg复制进来,新建freetype_test.cpp程序
在这里插入图片描述运行测试()

g++ -o freetype_test freetype_test.cpp `pkg-config --cflags --libs opencv` -I/usr/local/include/freetype2/ -lfreetype -lm 1 源码

#include <ft2build.h> #include FT_FREETYPE_H #include <highgui.h> #include <wchar.h> #include <assert.h> #include <locale.h> #include <ctype.h> #include <opencv2/opencv.hpp> #include<iostream> using namespace std; using namespace cv; class CvText {//================================================================//================================================================ public:/*** 装载字库文件*/CvText(const char *freeType);virtual ~CvText();//================================================================//================================================================/*** 获取字体。目前有些参数尚不支持。** param font 字体类型, 目前不支持* param size 字体大小/空白比例/间隔比例/旋转角度* param underline 下画线* param diaphaneity 透明度** sa setFont, restoreFont*/void getFont(int *type,CvScalar *size = NULL, bool *underline = NULL, float *diaphaneity = NULL);/*** 设置字体。目前有些参数尚不支持。** param font 字体类型, 目前不支持* param size 字体大小/空白比例/间隔比例/旋转角度* param underline 下画线* param diaphaneity 透明度** sa getFont, restoreFont*/void setFont(int *type,CvScalar *size = NULL, bool *underline = NULL, float *diaphaneity = NULL);/*** 恢复原始的字体设置。** sa getFont, setFont*/void restoreFont();//================================================================//================================================================/*** 输出汉字(颜色默认为黑色)。遇到不能输出的字符将停止。** param img 输出的影象* param text 文本内容* param pos 文本位置** return 返回成功输出的字符长度,失败返回-1。*/int putText(cv::Mat &frame, const char *text, CvPoint pos);/*** 输出汉字(颜色默认为黑色)。遇到不能输出的字符将停止。** param img 输出的影象* param text 文本内容* param pos 文本位置** return 返回成功输出的字符长度,失败返回-1。*/int putText(cv::Mat &frame, const wchar_t *text, CvPoint pos);/*** 输出汉字。遇到不能输出的字符将停止。** param img 输出的影象* param text 文本内容* param pos 文本位置* param color 文本颜色** return 返回成功输出的字符长度,失败返回-1。*/int putText(cv::Mat &frame, const char *text, CvPoint pos, CvScalar color);/*** 输出汉字。遇到不能输出的字符将停止。** param img 输出的影象* param text 文本内容* param pos 文本位置* param color 文本颜色** return 返回成功输出的字符长度,失败返回-1。*/int putText(cv::Mat &frame, const wchar_t *text, CvPoint pos, CvScalar color);//================================================================//================================================================ private:// 输出当前字符, 更新m_pos位置void putWChar(cv::Mat &frame, wchar_t wc, CvPoint &pos, CvScalar color);//================================================================//================================================================ private:FT_Library m_library; // 字库FT_Face m_face; // 字体 //================================================================ //================================================================ // 默认的字体输出参数int m_fontType;CvScalar m_fontSize;bool m_fontUnderline;float m_fontDiaphaneity;//================================================================//================================================================ }; int main() {cv::Mat img = imread("lena.jpg");CvText text("simhei.ttf");const char *msg = "黑 体freetype";//字库要求输入中文时中间必须有一个间隔float p = 0.5;text.setFont(NULL, NULL, NULL, &p); // 透明处理text.putText(img, msg, cvPoint(30, 30), CV_RGB(255, 255, 0));imshow("freetype_test", img);waitKey(-1);return 0; } CvText::CvText(const char *freeType) {assert(freeType != NULL);// 打开字库文件, 创建一个字体if (FT_Init_FreeType(&m_library)) throw;if (FT_New_Face(m_library, freeType, 0, &m_face)) throw;// 设置字体输出参数restoreFont();// 设置C语言的字符集环境setlocale(LC_ALL, ""); } // 释放FreeType资源 CvText::~CvText() {FT_Done_Face(m_face);FT_Done_FreeType(m_library); } // 设置字体参数: // // font - 字体类型, 目前不支持 // size - 字体大小/空白比例/间隔比例/旋转角度 // underline - 下画线 // diaphaneity - 透明度 void CvText::getFont(int *type, CvScalar *size, bool *underline, float *diaphaneity) {if (type) *type = m_fontType;if (size) *size = m_fontSize;if (underline) *underline = m_fontUnderline;if (diaphaneity) *diaphaneity = m_fontDiaphaneity; } void CvText::setFont(int *type, CvScalar *size, bool *underline, float *diaphaneity) {// 参数合法性检查if (type){if (type >= 0) m_fontType = *type;}if (size){m_fontSize.val[0] = fabs(size->val[0]);m_fontSize.val[1] = fabs(size->val[1]);m_fontSize.val[2] = fabs(size->val[2]);m_fontSize.val[3] = fabs(size->val[3]);}if (underline){m_fontUnderline = *underline;}if (diaphaneity){m_fontDiaphaneity = *diaphaneity;}FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], 0); } // 恢复原始的字体设置 void CvText::restoreFont() {m_fontType = 0; // 字体类型(不支持)m_fontSize.val[0] = 30; // 字体大小m_fontSize.val[1] = 0.5; // 空白字符大小比例m_fontSize.val[2] = 0.1; // 间隔大小比例m_fontSize.val[3] = 0; // 旋转角度(不支持)m_fontUnderline = false; // 下画线(不支持)m_fontDiaphaneity = 1.0; // 色彩比例(可产生透明效果) // 设置字符大小FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], 0); } // 输出函数(颜色默认为黑色) int CvText::putText(cv::Mat &frame, const char *text, CvPoint pos) {return putText(frame, text, pos, CV_RGB(255, 255, 255)); } int CvText::putText(cv::Mat &frame, const wchar_t *text, CvPoint pos) {return putText(frame, text, pos, CV_RGB(255, 255, 255)); } // int CvText::putText(cv::Mat &frame, const char *text, CvPoint pos, CvScalar color) {if (frame.empty()) return -1;if (text == NULL) return -1;//int i;for (i = 0; text[i] != ''; ++i){wchar_t wc = text[i];// 解析双字节符号if (!isascii(wc)) mbtowc(&wc, &text[i++], 2);// 输出当前的字符putWChar(frame, wc, pos, color);}return i; } int CvText::putText(cv::Mat &frame, const wchar_t *text, CvPoint pos, CvScalar color) {if (frame.empty()) return -1;if (text == NULL) return -1;//int i;for (i = 0; text[i] != ''; ++i){// 输出当前的字符putWChar(frame, text[i], pos, color);}return i; } // 输出当前字符, 更新m_pos位置 void CvText::putWChar(cv::Mat &frame, wchar_t wc, CvPoint &pos, CvScalar color) {// 根据unicode生成字体的二值位图IplImage temp=(IplImage) frame;IplImage* img = &temp;FT_UInt glyph_index = FT_Get_Char_Index(m_face, wc);FT_Load_Glyph(m_face, glyph_index, FT_LOAD_DEFAULT);FT_Render_Glyph(m_face->glyph, FT_RENDER_MODE_MONO);//FT_GlyphSlot slot = m_face->glyph;// 行列数int rows = slot->bitmap.rows;int cols = slot->bitmap.width;//for (int i = 0; i < rows; ++i){for (int j = 0; j < cols; ++j){int off = ((img->origin == 0) ? i : (rows - 1 - i))* slot->bitmap.pitch + j / 8;if (slot->bitmap.buffer[off] & (0xC0 >> (j % 8))){int r = (img->origin == 0) ? pos.y - (rows - 1 - i) : pos.y + i;;int c = pos.x + j;if (r >= 0 && r < img->height&& c >= 0 && c < img->width){CvScalar scalar = cvGet2D(img, r, c);// 进行色彩融合float p = m_fontDiaphaneity;for (int k = 0; k < 4; ++k){scalar.val[k] = scalar.val[k] * (1 - p) + color.val[k] * p;}cvSet2D(img, r, c, scalar);}}} // end for} // end for // 修改下一个字的输出位置double space = m_fontSize.val[0] * m_fontSize.val[1];double sep = m_fontSize.val[0] * m_fontSize.val[2];pos.x += (int)((cols ? cols : space) + sep); }

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365

(二) VS2017+freetype2.9.1

1. 下载

链接点这儿:http://download.savannah.gnu.org/releases/freetype/

2. 解压及配置

进入freetype-2.xbuildswindowsvc2010,打开工程并编译(编译选项可选);

在freetype-2.xobjswindowsvc2010里可看到生成的lib文件;

添加包含目录路径:freetype-2.xinclude
添加库目录路径:freetype-2.xobjswindowsvc2010
添加附加依赖项:(eg.)freetype2410_D.lib
(便于管理,也可以把include和objswindowsvc2010放在一个单独的文件夹中,分别名为include和lib);

3. 一个简单的Demo

参考链接:freetype输出中文

相关知识

SquareLine Studio 1.3.1 添加中文字体库并生成嵌入式点阵字体
字体库管理
字体库大全
ai生成字体库
探索Source Han TrueType:一款跨语言的开源字体库
word字体库
【花案图形字体和CAD字体库大全哪个好用】花案图形字体和CAD字体库大全对比-ZOL下载
Android 字体库的使用。引入外部字体
绘制玫瑰花并添加文字python
图片转web字体库,如何制作web字体库

网址: 【嵌入式】利用freetype字体库(绘制中文) https://m.huajiangbk.com/newsview742084.html

所属分类:花卉
上一篇: 韩愈
下一篇: NX二次开发:字体的调用