美文网首页
cImg库绘制自定义字体

cImg库绘制自定义字体

作者: 何亮hook_8285 | 来源:发表于2022-10-29 01:19 被阅读0次

简介

cImg是C++图像处理库,在使用cimg库时发现绘制文本不太友好,不能指定自定义字体,所以本文提供的代码能让cimg库绘制TTF字体。

计算机显示文字过程

  • 给定一个文字'A':0x41,"中":可能有GBK、unicode 等编码,可以确定它的编码值

  • 根据编码值从字体文件中找到"glyph"字形 ,(由于字体文件可以是GBK、unicode等,在字库文件前还存有字符映射表charmaps,支持多种编码)

  • 设置字体大小

  • 用某些函数把"glyph"字形里的点缩放设置的大小

  • 转换为位图点阵

  • 在LCD等显示器中显示出来

CImg库绘制自定义字体

以下代码使用到freetype库加载指定的ttf字体文件,将字符转位图、并且输出cimg图像中。


#define cimg_use_png
#define cimg_use_jpeg
#define cimg_use_tiff
#include <CImg.h>
#include <freetype/freetype.h>


/// 初始化freetype结构体
/// \param ftlib 字体库
/// \param face 字体内容
/// \param fontFullName ttf字体路径
void initFreetype( FT_Library& ftlib,FT_Face& face,const std::string& fontFullName){
    FT_Error fterr;
    if((fterr = FT_Init_FreeType( &ftlib ))) {
        throw "初始化FT_Library库失败";
    }

    if((fterr = FT_New_Face(ftlib, fontFullName.c_str(), 0, &face))){
        if(fterr == FT_Err_Unknown_File_Format) {
            throw "未找到ttf字体文件";
        } else {
            throw "初始化FT_Face失败";
        }

    }

}

/**
 * 绘制每一个字体
 * @param glyphSlot 字形数据
 * @param image  绘制图片
 * @param shiftX  绘制x坐标
 * @param shiftY  绘制y坐标
 * @param fontColor 字体颜色
 */
void drawGlyph(FT_GlyphSlot& glyphSlot,cimg_library::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;
            }
        }
    }

}

/**
 *
 * @param face 字体对象
 * @param image 绘制图片
 * @param heightText 字体高度
 * @param text  绘制文字
 * @param leftTopX  x坐标
 * @param leftTopY y坐标
 * @param fontColor 字体颜色
 * @param separateGlyphWidth 每一个文字间隔,默认1
 */
void drawText(FT_Face& face,cimg_library::CImg<unsigned char>& image,const int& heightText,const std::wstring& text,const int& leftTopX,const int& leftTopY,unsigned char fontColor[] = NULL,int separateGlyphWidth=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 "在字体库加载加载文字失败!! \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 + separateGlyphWidth;

    }

}

/**
 * 销毁FT_Library和FT_Face
 * @param ftlib
 * @param face
 */
void closeFreetype(FT_Library& ftlib,FT_Face& face){
    FT_Done_Face(face);
    FT_Done_FreeType(ftlib);
}


int main() {
    FT_Library ftlib;
    FT_Face face;
    char *ttfFilename="d:\\simhei.ttf";
    initFreetype(ftlib, face, ttfFilename);
    cimg_library::CImg<unsigned char> img(640, 400, 1, 3);
    img.fill(255);
    unsigned char redFontColor[] = {0, 0, 0};
    drawText(face, img, 15, L"heliang", 0, 0, redFontColor,1);
    img.save_bmp("d:\\imgfont.bmp");
    closeFreetype(ftlib, face);
    return 0;    
}

相关文章

  • cImg库绘制自定义字体

    简介 cImg是C++图像处理库,在使用cimg库时发现绘制文本不太友好,不能指定自定义字体,所以本文提供的代码能...

  • Android xml 中绘制图形

    布局xml文件中使用imageview控件 (2)绘制直线 (3)绘制矩形 (4)使用自定义字体 把****字体*...

  • CImg中文手册1

    本手册主要介绍CImg库主要的类和函数: 类库结构 CImg仅包含一个头文件CImg.h;提供了一系列的C++模板...

  • CImg中文文档

    CImg是一个非常精简的开源C++图像处理库;Github项目地址;最大的特点是整个库就一个CImg.h文件;作者...

  • ios 系统字体 以及添加自定义字体

    1.准备字体库(.ttf .otf等格式) 添加自定义字体的前提是要有字体库,字体库可以百度,也可以从mac上找...

  • 动态注册字体

    项目中如果只是使用几种固定的字体,可以本地添加自定义字体,可以参考iOS加入自定义字体库[https://www....

  • iOS在项目中使用自定义字体

    iOS 自定义字体是指,使用自己从外部导入的字体库使用在对应的文本显示中。 一般的iOS自定义的字体库是 .ttf...

  • 微信小程序加入自定义字体

    SVG转字体库 svg转字体可以使用 https://icomoon.io/app/ 微信中使用自定义字体 字体文...

  • 第三方库

    自定义字体库:https://github.com/chrisjenx/CalligraphyLeakCanary...

  • iOS在应用中添加自定义字体

    iOS在应用中添加自定义字体 一、在应用中添加自定义字体的步骤 1、网上提供的字体库有很多,下载完成后,将其导入工...

网友评论

      本文标题:cImg库绘制自定义字体

      本文链接:https://www.haomeiwen.com/subject/qtrqtdtx.html