使用freetype库将文字嵌入到bmp图片中 学习笔记

14 篇文章 0 订阅
1 篇文章 0 订阅

原文章链接:http://blog.csdn.net/u010385177/article/details/46929503
当时也是工作原因,需要用到freetype2来处理字符串,后来找到了这篇blog,虽然平台不一致(他的是windows程序,而我是要Linux程序),但毕竟都是C的实现,所以照着他的例子实现起来。

最终发现原文章有一些BUG(或许平台不一致,但在linux平台上确定存在的几个问题):
1 bmp的结构体没有对齐。所以在源代码中,需要添加对齐代码的语句:

//两字节对齐
#ragma pack (2)

2 字体是写入到了bmp图片中去了,但少了数据。因为在申请arrayColor空间的过程中,少申请了空间。

//原文章中的申请空间代码:
arrayColor=new  IMAGEDATA[nWidth*nHeight];   
//应改为
arrayColor=new  IMAGEDATA[nWidth*nHeight*sizeof(IMAGEDATA)];

3 新生成的bmp与原bmp相比,它是倒着的(虽然字符串的正常的)。这个问题主要出现在下面两断代码中(修复方法见帖出来的代码):

arrayColor[(i+100)*strInfo.biWidth+j+bitmap_width_sum+100].green=0;
arrayColor[(i+100)*strInfo.biWidth+j+bitmap_width_sum+100].blue=0;  
.
.
.
    strInfo.biHeight = -strInfo.biHeight;//正数是从数组的末尾开始扫描,负数表示从数组的开始端开始扫描 

所以,在原文章的基础上,做了一些问题的修复,最后也贴出来,供大家参考:

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <wchar.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_OUTLINE_H

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef long LONG;

#pragma pack (2)
typedef struct tagBITMAPFILEHEADER{
    WORD bfType;
    DWORD bfSize;
    WORD bfReserved1;
    WORD bfReserved2;
    DWORD bfOffBits;
}BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER{
    DWORD biSize;
    LONG biWidth;
    LONG biHeight;
    WORD biPlanes;
    WORD biBitCount;
    DWORD biCompression;
    DWORD biSizeImage;
    LONG biXPelsPerMeter;
    LONG biYPelsPerMeter;
    DWORD biClrUsed;
    DWORD biClrImportant;
}BITMAPINFOHEADER;

typedef struct tagRGBQUAD{
    BYTE rgbBlue;
    BYTE rgbGreen;
    BYTE rgbRed;
    BYTE rgbReserved;
}RGBQUAD;

typedef struct tagIMAGEDATA{
    BYTE blue;
    BYTE green;
    BYTE red;
}IMAGEDATA;


BITMAPFILEHEADER strHead;
BITMAPINFOHEADER strInfo;
IMAGEDATA *arrayColor;
LONG nWidth;
LONG nHeight;

void showBmpHead(BITMAPFILEHEADER head)
{
    printf("bmp header:\n");
    printf("bfType:%0x\n",head.bfType);
    printf("size:%d\n",head.bfSize);
    printf("offsetSize:%d\n",head.bfOffBits);
}

void showBmpInfoHead(BITMAPINFOHEADER infoHead)
{
    printf("bmp info header:\n");
    printf("bmp width:%d\n",infoHead.biWidth);
    printf("bmp height:%d\n",infoHead.biHeight);
}

int WordInsert2Bmp(char *strFile)
{
    FILE *fpi,*fpw;
    fpi = fopen(strFile,"rb");
    FT_Library pFTLib = NULL;
    FT_Face pFTFace = NULL;
    FT_Error error = 0;
    error = FT_Init_FreeType(&pFTLib);
    if(error){
        pFTLib = 0;
        printf("There is some error when init library\n");
        return -1;
    }

    error = FT_New_Face(pFTLib, "/home/topsluo/Russo_One.ttf", 0, &pFTFace);
    if(error){
        printf("Open font failed\n");
        return -1;
    }

    FT_Set_Char_Size(pFTFace, 0, 16*64, 300, 300);
    FT_Glyph glyph;
    wchar_t *wszString = L"TEST    BY    TOPSLUO";
    WORD word;
    if(fpi != NULL){
        fread(&strHead, 1, sizeof(struct tagBITMAPFILEHEADER), fpi);
        if(0x4D42 != strHead.bfType)
        {
            printf("The file is not a bmp file\n");
            return -1;
        }

        showBmpHead(strHead);
        fread(&strInfo, 1, sizeof(struct tagBITMAPINFOHEADER), fpi);
        showBmpInfoHead(strInfo);
        nWidth = strInfo.biWidth;
        nHeight = strInfo.biHeight;
        DWORD size = nWidth * nHeight;
        arrayColor = (IMAGEDATA *)malloc(nWidth * nHeight * sizeof(struct tagIMAGEDATA));
        fread(arrayColor, 1, nWidth*nHeight*sizeof(struct tagIMAGEDATA), fpi);
        int bitmap_width_sum = 0;
        int wszStringLen = wcslen(wszString)+1;
        printf("wszStringLen: %d\n",wszStringLen);
        for(int k=0; k < wszStringLen; k++)
        {
            memcpy(&word, wszString+k, 2);
            FT_Load_Glyph(pFTFace, FT_Get_Char_Index(pFTFace,word), FT_LOAD_DEFAULT);
            error = FT_Get_Glyph(pFTFace->glyph, &glyph);
            FT_Glyph_To_Bitmap(&glyph, ft_render_mode_normal, 0, 1);
            FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;
            FT_Bitmap  *bitmap = &bitmap_glyph->bitmap;
            for(int i=0;i<bitmap->rows;++i)
            {
                for(int j=0;j<bitmap->width;++j)
                {
                    if(bitmap->buffer[i * bitmap->width +j] != 0)
                    {
                        //arrayColor[(i+100)*strInfo.biWidth+j+bitmap_width_sum+100].green = 0;
                        //arrayColor[(i+100)*strInfo.biWidth+j+bitmap_width_sum+100].blue = 0;
                        arrayColor[(strInfo.biHeight-i)*strInfo.biWidth+j+bitmap_width_sum].green = 0;
                        arrayColor[(strInfo.biHeight-i)*strInfo.biWidth+j+bitmap_width_sum].blue = 0;
                    }
                }
            }
            bitmap_width_sum += bitmap->width + 10;
        }
        FT_Done_Glyph(glyph);
        glyph = NULL;
        FT_Done_Face(pFTFace);
        pFTFace = NULL;
        FT_Done_FreeType(pFTLib);
        pFTLib = NULL;
        fclose(fpi);
    }
    else{
        printf("file open error\n");
        return -1;
    }

    if((fpw=fopen("b.bmp","wb")) == NULL){
        printf("Create the bmp file error\n");
        return -1;
    }
    fwrite(&strHead,1,sizeof(struct tagBITMAPFILEHEADER),fpw);
    strInfo.biHeight = strInfo.biHeight;
    fwrite(&strInfo, 1, sizeof(struct tagBITMAPINFOHEADER), fpw);
    fwrite(arrayColor,1, nWidth*nHeight*sizeof(struct tagIMAGEDATA),fpw);
    fclose(fpw);
    return 0;
}

int main()
{
    printf("%d\n",sizeof(struct tagBITMAPFILEHEADER));
    printf("%d\n",sizeof(struct tagBITMAPINFOHEADER));
    WordInsert2Bmp("canvas.bmp");
    return 0;
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值