//! @brief PBM(1byte,テキスト)を書き込む //! @param [in] fname ファイル名 //! @param [in] width 画像の幅 //! @param [in] height 画像の高さ //! @param [in] p 画像のメモリへのアドレス //! @details 1画素1Byteのメモリを渡すと、0,1テキストでファイル名fnameで書き込む void pbmP1_Write(const char* const fname, const int width, const int height, const unsigned char* const p) { // PPM ASCII FILE* fp = fopen(fname, "wb"); fprintf(fp, "P1\n%d\n%d\n", width, height); size_t k = 0; for (size_t i = 0; i < (size_t)height; i++) { for (size_t j = 0; j < (size_t)width; j++) { fprintf(fp, "%d ", p[k] ? 0 : 1); k++; } fprintf(fp, "\n"); } fclose(fp); }
この時、以下のコードで、以下のpixel_heightで出力すると、正常に出力されない。文字サイズが小さすぎると結果が壊れる。
#include <ft2build.h> #include FT_FREETYPE_H #pragma warning(disable:4996) #pragma comment(lib,"freetype.lib") int main() { FT_Library library; // handle to library FT_Error error; error = FT_Init_FreeType(&library); if (error) return -1; FT_Face face; // handle to face object //msgothic.ttc //meiryo.ttc // フォントファイル読み込み error = FT_New_Face( library, "C:\\Windows\\Fonts\\msgothic.ttc", 0, &face ); //文字コード指定 error = FT_Select_Charmap( face, // target face object FT_ENCODING_UNICODE // エンコード指定 ); if (error == FT_Err_Unknown_File_Format) return -1; else if (error) return -1;
int pixel_heigth =16;
//この二つの値でフォントサイズ調整 FT_Set_Pixel_Sizes( face, // handle to face object 0, // pixel_width pixel_heigth // pixel_height ); // 文字の取得 FT_ULong character = wchar_t(L'あ'); FT_UInt char_index = FT_Get_Char_Index(face, character); // グリフ(字の形状)読込 error = FT_Load_Glyph(face, char_index, FT_LOAD_RENDER); if (error) return -1; // ignore errors // 文字を画像化 FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); FT_Bitmap& glyphbitmap = face->glyph->bitmap; int Width = glyphbitmap.width; int Height = glyphbitmap.rows; pbmP1_Write(// ファイル保存 "C:\\test\\freetypetest.pbm", Width, Height, glyphbitmap.buffer ); // FreeType2の解放 FT_Done_Face(face); FT_Done_FreeType(library); }
これは(多分)、フォントサイズが小さいときはビットマップフォントが使われ、pixel_typeが変わってしまっているから。
FT_Bitmap_Convertで画像データを変換すれば、取り出したフォントの形式にかかわらず、8bppにできる。
FT_Bitmap glyphbitmap;// 新しい画像データ FT_Bitmap_Init(&glyphbitmap);// 新しい画像データの初期化 FT_Bitmap_Convert(library, &face->glyph->bitmap, &glyphbitmap, 1);// 文字画像を8bppに変換 int Width = glyphbitmap.width; int Height = glyphbitmap.rows; pgmP2_Write(// ファイル保存 "C:\\test\\freetypetest.pbm", Width, Height, 255, glyphbitmap.buffer ); FT_Bitmap_Done(library, &glyphbitmap);// 文字画像を解放
int main() { FT_Library library; // handle to library FT_Error error; error = FT_Init_FreeType(&library); if (error) return -1; FT_Face face; // handle to face object //msgothic.ttc //meiryo.ttc // フォントファイル読み込み error = FT_New_Face( library, "C:\\Windows\\Fonts\\msgothic.ttc", 0, &face ); //文字コード指定 error = FT_Select_Charmap( face, // target face object FT_ENCODING_UNICODE // エンコード指定 ); if (error == FT_Err_Unknown_File_Format) return -1; else if (error) return -1; int pixel_heigth = 16; //この二つの値でフォントサイズ調整 FT_Set_Pixel_Sizes( face, // handle to face object 0, // pixel_width pixel_heigth // pixel_height ); // 文字の取得 FT_ULong character = wchar_t(L'あ'); FT_UInt char_index = FT_Get_Char_Index(face, character); // グリフ(字の形状)読込 error = FT_Load_Glyph(face, char_index, FT_LOAD_RENDER | FT_LOAD_COLOR); if (error) return -1; // ignore errors // 文字を画像化 FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
FT_Bitmap glyphbitmap; FT_Bitmap_Init(&glyphbitmap); FT_Bitmap_Convert(library, &face->glyph->bitmap, &glyphbitmap, 1); int Width = glyphbitmap.width; int Height = glyphbitmap.rows; pgmP2_Write(// ファイル保存 "C:\\test\\freetypetest.pbm", Width, Height, 255, glyphbitmap.buffer ); FT_Bitmap_Done(library, &glyphbitmap);
// FreeType2の解放 FT_Done_Face(face); FT_Done_FreeType(library); }
フォントサイズによってpixel_modeが違うことがある。以下のコードで確認する。
switch (face->glyph->bitmap.pixel_mode) { case FT_PIXEL_MODE_NONE: printf("FT_PIXEL_MODE_NONE"); break; case FT_PIXEL_MODE_MONO: printf("FT_PIXEL_MODE_MONO"); break; case FT_PIXEL_MODE_GRAY: printf("FT_PIXEL_MODE_GRAY"); break; case FT_PIXEL_MODE_GRAY2: printf("FT_PIXEL_MODE_GRAY2"); break; case FT_PIXEL_MODE_GRAY4: printf("FT_PIXEL_MODE_GRAY4"); break; case FT_PIXEL_MODE_LCD: printf("FT_PIXEL_MODE_LCD"); break; case FT_PIXEL_MODE_LCD_V: printf("FT_PIXEL_MODE_LCD_V"); break; case FT_PIXEL_MODE_BGRA: printf("FT_PIXEL_MODE_BGRA"); break; } getchar();
pixel height | pixel_mode |
---|---|
16 | FT_PIXEL_MODE_MONO |
32 | FT_PIXEL_MODE_GRAY |