スポンサーリンク

FreeType2でFT_RENDER_MODE_MONOを指定したときpixel_mode==FT_PIXEL_MODE_MONOなデータのビット列をピクセルにする

FreeType2でFT_RENDER_MODE_MONOを指定すると、pixel_modeがFT_PIXEL_MODE_MONOになる。

この時、画像データは1ビット1ピクセルの格好をしているので、それを取り出す必要がある。

注意点は、各ビット列をreverse、つまり向きを逆にしてやる必要があることと、例えば幅10ピクセルなら2バイト10ビットであり、残りの6ビットが未使用領域になっているので読み飛ばさなければならない。

#include <vector>

#include <ft2build.h>
#include FT_FREETYPE_H

#include <freetype/ftstroke.h>

#pragma warning(disable:4996)

#pragma comment(lib,"freetype.lib")

#include <bitset>

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 = 13;

    //この二つの値でフォントサイズ調整
    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_DEFAULT/*FT_LOAD_RENDER*/);
    if (error)
        return -1; // ignore errors

    // 文字を画像化
    FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO/*FT_RENDER_MODE_NORMAL*/);


      
    int Width = face->glyph->bitmap.width;
    int Height = face->glyph->bitmap.rows;
    ////////////////////////////////////////
    ////////////////////////////////////////
    // face->glyph->bitmap.buffer には1ドット1ビットで入っている

    // 画素数
    const int size = face->glyph->bitmap.rows * face->glyph->bitmap.width;

    std::vector<unsigned char> bools;
    int k = 0;
    while (bools.size() < size) {

        // 各ビットに[]でアクセスできるようにする
        std::bitset<8> bits = face->glyph->bitmap.buffer[k];

        // ビットの向きが桁の大きいほうにより左側のドットが入っているので
        // 逆側から格納する
        for (int i = 7; i >= 0; i--) {
            bools.push_back(bits[i]);

            // 例えば画素数 が10の時は、2byte使用、ただし[8bit] + [2bit , 余り6bitは使わない]
            // という構造をしているので、画像の幅の分だけピクセルがたまったら
            // そのバイトの残りは捨てて次の行の格納を開始する
            if (bools.size() % Width == 0)
                break;
        }

        k++;
    }
    
    
    ////////////////////////////////////////
    ////////////////////////////////////////

    FILE* fp = fopen("C:\\test\\freetypetest.pbm", "wb");
    fprintf(fp, "P1\n%d %d\n", Width, Height);
    for (int i = 0; i < bools.size();i++) {
        fprintf(fp, "%s", bools[i]?"1":"0");
    }
    fclose(fp);
    ////////////////////////////////////////
    ////////////////////////////////////////

      
    // FreeType2の解放
    FT_Done_Face(face);
    FT_Done_FreeType(library);
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: