您的位置:首页 > 运维架构 > Linux

CImg应用-输出中文字符(CentOS 6.5)

2015-01-30 09:11 211 查看
编程工具:Eclipse(C/C++)

CImg版本:1.6.0

 

CImg本身不支持中文,本文通过FreeType和TTF字体文件实现中文字体输出,其它字体的输出也可借鉴此方式实现。

 

#include <iostream>

using namespace std;

 

#define cimg_OS 0

#include </home/hqq/公共的/CImg-1.6.0_rolling150120/CImg.h>

using namespace cimg_library;

 

#include <ft2build.h>

#include FT_FREETYPE_H

 

void initFreetype(

    FT_Library& ftlib,

    FT_Face& face,

    const std::string& fontFullName

){

    FT_Error fterr;

 

    if((fterr = FT_Init_FreeType( &ftlib ))) {

        throw "Error init freetype";

    }

 

    if((fterr = FT_New_Face(ftlib, fontFullName.c_str(), 0, &face))){

        if(fterr == FT_Err_Unknown_File_Format) {

            throw "Error feetype, Unsupported font";

        } else {

            throw "Error feetype, new face";

        }

    }

}

 

void closeFreetype(

    FT_Library& ftlib,

    FT_Face& face

){

    FT_Done_Face(face);

    FT_Done_FreeType(ftlib);

}

 

void drawGlyph(

    FT_GlyphSlot& glyphSlot,

    CImg<unsigned char>& image,

    const int& shiftX,

    const int& shiftY,

    unsigned char fontColor[] = NULL

){

    unsigned char buff[] = {255, 255, 255};

    if (fontColor == NULL){

        fontColor = buff;

    }

 

    float alpha = 0;

    for (int y = 0; y < glyphSlot->bitmap.rows; ++y){

        for (int x = 0; x < glyphSlot->bitmap.width; ++x){

 

            unsigned char glyphValue = glyphSlot->bitmap.buffer[y * glyphSlot->bitmap.width + x];

            alpha = (255.0f - glyphValue) / 255.0f;

 

            cimg_forC(image, c){

                unsigned char value = (float) glyphValue*fontColor[c]/(255.0f);

                image(x + shiftX, y + shiftY, c) =

                alpha * image(x + shiftX, y + shiftY, c) + (1.0 - alpha) * value;

            }

        }

    }

}

 

void drawText(

    FT_Face& face,

    CImg<unsigned char>& image,

    const int& heightText,

    const std::wstring& text,

    const int& leftTopX,

    const int& leftTopY,

    unsigned char fontColor[] = NULL,

    const int separeteGlyphWidth = 1

){

 

    FT_Set_Pixel_Sizes(face, 0, heightText);

    FT_GlyphSlot glyphSlot = face->glyph;

 

    int shiftX = leftTopX;

    int shiftY = 0;

    for(int numberSymbol = 0; numberSymbol < text.length(); ++numberSymbol){

        shiftY = leftTopY;

 

        bool isSpace = false;

        FT_ULong symbol = text.at(numberSymbol);

        if (symbol == ' ') {

            symbol = 'a';

            isSpace = true;

        }

 

        if(FT_Load_Char(face, symbol, FT_LOAD_RENDER)){

           throw "Error, glyph not load!! \n";

        }

 

        float shiftFactor = glyphSlot->bitmap.rows - glyphSlot->bitmap_top;

        shiftY += shiftFactor;

        shiftY +=  (heightText > glyphSlot->bitmap.rows) ? heightText - glyphSlot->bitmap.rows : 0;

 

        if(!isSpace){

            drawGlyph(glyphSlot, image, shiftX, shiftY, fontColor);

        }

        shiftX += glyphSlot->bitmap.width + separeteGlyphWidth;

    }

}

 

int main() {

   FT_Library ftlib;

   FT_Face face;

 

   try{

   initFreetype(ftlib, face, "/home/hqq
a615
/公共的/字体/华文新宋.ttf");

 

  CImg<unsigned char> img(640, 400, 1, 3);

  img.fill(255);

 

  unsigned char redFontColor[] = {255, 0, 0};

 

  drawText(face, img, 50, L"你好!", 0, 0, redFontColor);

 

  img.save_bmp("/home/hqq/HelloCIMG.bmp");

  closeFreetype(ftlib, face);

   } catch(char const* e) {

   std::cout << "Exception: " << e << std::endl;

   }

 

cout << "!!!恭喜成功!!!" << endl;

return 0;

}

 

FreeType不在头文件不在包含目录中,所以在使用时,需要包含头文件所在目录:

Project->Properties->C/C++ Build->Settings->Cross G++ Compiler->Includes

在Include path(-l)中添加freetype头文件所在目录。

 

pthread和freetype库不是 Linux 系统默认的库,所以在使用时,需要链接该库:

Project->Properties->C/C++ Build->Settings->GCC C++ Linker->Libraries

在Libraries(-l)中添加pthread,freetype即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: