java 解析ttf字体文件_stb_truetype解析ttf字体并将其保存到图片中
一、前言
这段时间的工作需要研究stb_truetype库,因此本篇文章记录一下该库的基本用法。stb_truetype是一个常见字体加载库, 只有一个头文件, 功能虽没有freetype库强大,但代码量小很多,在Flash非常小的开发板上也可以用,觉得freetype库太大的,建议使用stb_truetype库。
stb库的GitHub仓库:https://github.com/nothings/stb。
二、stb_truetype解析ttf字体
使用stb_truetype库解析ttf字体的步骤通常如下:
1、加载并初始化ttf字体文件;
2、设置字体大小(字号)并计算缩放比例;
3、获取垂直方向上的度量并根据缩放比例调整,比如字高、行间距等;
4、获取水平方向上的度量,比如字宽、字间距等;
5、获取字符图片的边框(每个字符转化为图像的边界);
6、调整每个字体图像的宽高(代码中的x、y),并渲染字体;
至此,解析ttf字体已完成,附加步骤为使用stb_image_write库将渲染出来的图像保存为本地图片,下面直接上代码:
注意:在包含stb_truetype.h头文件的时候需要定义STB_TRUETYPE_IMPLEMENTATION,否则将会无法使用。
#include
#include
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h" /* http://nothings.org/stb/stb_image_write.h */
#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h" /* http://nothings.org/stb/stb_truetype.h */
int main(int argc, const char *argv[])
{
/* 加载字体(.ttf)文件 */
long int size = 0;
unsigned char *fontBuffer = NULL;
FILE *fontFile = fopen("font/default.ttf", "rb");
if (fontFile == NULL)
{
printf("Can not open font file!\n");
return 0;
}
fseek(fontFile, 0, SEEK_END); /* 设置文件指针到文件尾,基于文件尾偏移0字节 */
size = ftell(fontFile); /* 获取文件大小(文件尾 - 文件头 单位:字节) */
fseek(fontFile, 0, SEEK_SET); /* 重新设置文件指针到文件头 */
fontBuffer = calloc(size, sizeof(unsigned char));
fread(fontBuffer, size, 1, fontFile);
fclose(fontFile);
/* 初始化字体 */
stbtt_fontinfo info;
if (!stbtt_InitFont(&info, fontBuffer, 0))
{
printf("stb init font failed\n");
}
/* 创建位图 */
int bitmap_w = 512; /* 位图的宽 */
int bitmap_h = 128; /* 位图的高 */
unsigned char *bitmap = calloc(bitmap_w * bitmap_h, sizeof(unsigned char));
/* "STB"的 unicode 编码 */
char word[20] = {0x53, 0x54, 0x42};
/* 计算字体缩放 */
float pixels = 64.0; /* 字体大小(字号) */
float scale = stbtt_ScaleForPixelHeight(&info, pixels); /* scale = pixels / (ascent - descent) */
/**
* 获取垂直方向上的度量
* ascent:字体从基线到顶部的高度;
* descent:基线到底部的高度,通常为负值;
* lineGap:两个字体之间的间距;
* 行间距为:ascent - descent + lineGap。
*/
int ascent = 0;
int descent = 0;
int lineGap = 0;
stbtt_GetFontVMetrics(&info, &ascent, &descent, &lineGap);
/* 根据缩放调整字高 */
ascent = roundf(ascent * scale);
descent = roundf(descent * scale);
int x = 0; /*位图的x*/
/* 循环加载word中每个字符 */
for (int i = 0; i < strlen(word); ++i)
{
/**
* 获取水平方向上的度量
* advanceWidth:字宽;
* leftSideBearing:左侧位置;
*/
int advanceWidth = 0;
int leftSideBearing = 0;
stbtt_GetCodepointHMetrics(&info, word[i], &advanceWidth, &leftSideBearing);
/* 获取字符的边框(边界) */
int c_x1, c_y1, c_x2, c_y2;
stbtt_GetCodepointBitmapBox(&info, word[i], scale, scale, &c_x1, &c_y1, &c_x2, &c_y2);
/* 计算位图的y (不同字符的高度不同) */
int y = ascent + c_y1;
/* 渲染字符 */
int byteOffset = x + roundf(leftSideBearing * scale) + (y * bitmap_w);
stbtt_MakeCodepointBitmap(&info, bitmap + byteOffset, c_x2 - c_x1, c_y2 - c_y1, bitmap_w, scale, scale, word[i]);
/* 调整x */
x += roundf(advanceWidth * scale);
/* 调整字距 */
int kern;
kern = stbtt_GetCodepointKernAdvance(&info, word[i], word[i + 1]);
x += roundf(kern * scale);
}
/* 将位图数据保存到1通道的png图像中 */
stbi_write_png("STB.png", bitmap_w, bitmap_h, 1, bitmap, bitmap_w);
free(fontBuffer);
free(bitmap);
return 0;
}
运行后可以见STB.png图片,效果如下:
三、总结
以上便是stb_truetype库的基本用法,可以看出使用过程比较简单,其中需要调整的参数主要是字体大小(字号),使用过程中需要注意以下两点:
1、上面已经提过,这里再提一遍,在包含stb_truetype.h头文件的时候需要定义STB_TRUETYPE_IMPLEMENTATION,否则将会无法使用。
2、调用stb_truetype库函数传入的字符编码必须是unicode编码。
java 解析ttf字体文件_stb_truetype解析ttf字体并将其保存到图片中相关推荐
- php ttf 字体 url,window_TTF字体文件如何安装 TTF文件打不开解决方法,TTF文件是Windows系统下的字体文 - phpStudy...
TTF字体文件如何安装 TTF文件打不开解决方法 TTF文件是Windows系统下的字体文件,可通过系统自带的字体安装程序直接安装添加字体,比如常用的"仿宋_GB2312"字体就可 ...
- java引入外部字体_Java中如何自定义字体文件(引用外部字体)?-字体文件
图源来自网络 有时候我们在程序中,会使用到Java字体,但不是所有的字体系统中都会有,我们就可能会使用外部自定义字体,这样在程序迁移部署中就会少些工作,最近在一个项目中使用到了自定义字体文件,理顺了, ...
- 误删计算机上字体文件夹,误删WIN98字体文件的恢复
1.重新安装Windows98: 2.从别的机器上将误删的字体文件拷贝还原. 第三种方法如下: 首先,在c:\\Windows\\inf目录下找到Windows98安装光盘的三个列表信息文件layou ...
- html字体文件太大,css字体文件包太大无法引入怎么处理?
前端开发的同学,我们经常会碰到需要还原设计稿中的特殊字体.这时,我们可能会采用两种方案: 1.使用photoshop将文本图层单独导出成图片; 2.直接引入改字体的字体库.ttf文件 首先第一种方案的 ...
- web引入font字体文件太大,字体抽取
当只有一个活动页面或者一小段文字需要引入特殊字体,字体文件往往会有十几兆或者几十兆,特别在移动端或者弱网情况下有相当差的体验,一个14M左右的文件就需要加载12秒... 所以针对一些小范围使用字体文件 ...
- css引入woff ttf,css引用跨域字体文件woff,eot,ttf问题
Apache服务器解决方法(在conf.或者.htaccess 均可添加,或者宝塔站点配置中修改) <FilesMatch "\.(ttf|otf|eot|woff|woff2)$&q ...
- java读取csv合适文件_解析-您可以推荐一个Java库来读取(并可能写入)CSV文件吗?...
Super CSV是读取/解析,验证和映射CSV文件到POJO的绝佳选择! 我们(Super CSV团队)刚刚发布了一个新版本(您可以从SourceForge或Maven下载它). 读取CSV文件 以 ...
- 深入Java虚拟机:Class文件实例解析
前面发了几篇学习笔记,但是看这些东西总是感觉很"玄乎",来一篇实战的东西来揭一下"JVM"的面纱,让"SSH"时代的童鞋们来熟悉一下Java ...
- 【无标题】JAVA解压ZIP文件并解析Excel(easyExcel)
返回值我用的是公司自定义的FT框架 具体返回值根据公司而定 一般在上传文件,PDF,Excel,zip压缩包时 后端基本都用MultipartFile接收 一定加上Http请求方便后续拼接路径 需求: ...
- android xml解析demo,Android解析自定义xml文件--Sax解析xml文件,测试demo(方案二)...
转载请注明出处:http://blog.csdn.net/droyon/article/details/9346657 Sax解析xml 以下是测试Demo 运行程序类 public class Te ...
最新文章
- 好系统U盘启动来说一说win10系统有必要更新到最新版本吗?
- matlab 投票法_SVM算法原理及其Matlab应用
- Post Content_Length exceeds the limit
- 代码大全阅读笔记02
- 神经信息学整理(2)-caianiello神经方程(1)
- 【记录】有关parseInt的讨论
- 变更控制管理流程图_制度是最好的老板,流程就是最好的管理!流程建立法则(附案例)...
- mysql 安装telnat_yum安装telnet服务
- WordPress简约博客主题模板Chen主题V1.2
- MySQL 日志文件
- ELK 收集多个日志文件
- idea搭建maven工程
- 永中Office 2004 增强版上市,试用版免费下载
- 微信公众号---收货地址共享接口
- 用uniapp组件写登录注册
- 横幅(banner)设计的成功技术
- Android 万能通用selector
- Andorid 拍照、从相册中选择图片兼容7.0uri
- 第1章 高瞻远瞩一一游戏开发面面观
- python控制台程序学生管理系统实验总结_管理信息系统实验总结报告
热门文章
- 使用MVPArms框架时,访问网络没响应。
- cad画圆如何确定圆心_CAD如何利用对象捕捉追踪功能来确定小圆圆心以及矩形的角点位置...
- 学习OpenCV(2)OpenCV初探-2
- MATLAB代码:全面ADMM算法代码,实现了三种ADMM迭代方式 参考文档:《基于串行和并行ADMM算法的电_气能量流分布式协同优化_瞿小斌》
- 采集工具有哪些-免费的采集工具下载
- 信捷plc用c语言编程视频,信捷PLC/触摸屏全套编程软件/学习教程视频资料 大全编程操作手册...
- AlterID.exe解决teamview商业使用
- 无线投屏视频经过服务器吗,无线投屏方案
- 【数学模型】基于Matlab实现洪水调度运算
- windows应用程序签名