日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java 解析ttf字体文件_stb_truetype解析ttf字体并将其保存到图片中

發布時間:2023/12/10 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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字体并将其保存到图片中的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。