使用GDlib在图片上绘制文本

来源:互联网 发布:网络剧青春那些事 编辑:程序博客网 时间:2024/05/29 21:16

GDlib安装

在ubuntu 17.04下选择从源码编译安装环境准备:

  • libpng,png格式支持; 执行apt install libpng-dev
  • libjpeg
  • libfreetype,字体支持
  • zlib
  • cmake

clone源代码并切换到目的tag,cd到源码根目录,执行以下命令:

cmake -DBUILD_TEST=1 -DENABLE_FREETYPE=1 -DENABLE_PNG=1 -DENABLE_JPEG=1 -DFREETYPE_INCLUDE_DIRS=/usr/local/include/freetype2/ ./makemake install

安装freetype2后cmake未找到,故手到指定了下freetype的路径-DFREETYPE_INCLUDE_DIRS=/usr/local/include/freetype2/
cmake可指定的部分选项有:

OPTION(ENABLE_PNG "Enable PNG support" 0)OPTION(ENABLE_LIQ "Enable libimagequant support" 0)OPTION(ENABLE_JPEG "Enable JPEG support" 0)OPTION(ENABLE_TIFF "Enable TIFF support" 0)OPTION(ENABLE_ICONV "Enable ICONV support" 0)OPTION(ENABLE_XPM "Enable XPM support" 0)OPTION(ENABLE_FREETYPE "Enable Freetype2 support" 0)OPTION(ENABLE_FONTCONFIG "Enable FontConfig support" 0)OPTION(ENABLE_WEBP "Enable WebP support" 0)if (BUILD_TEST)    ENABLE_TESTING()endif(BUILD_TEST)

执行测试可用:ctest

文本绘制函数

绘制文本主要是通过调用函数GD库内gdImageStringFT函数实现,该函数实现如下:

/** * Function: gdImageStringFT * * Render an UTF-8 string onto a gd image. * * Parameters: *  im       - The image to draw onto. *  brect    - The bounding rectangle as array of 8 integers where each pair *             represents the x- and y-coordinate of a point. The points *             specify the lower left, lower right, upper right and upper left *             corner. *  fg       - The font color. *  fontlist - The semicolon delimited list of font filenames to look for. *  ptsize   - The height of the font in typographical points (pt). *  angle    - The angle in radian to rotate the font counter-clockwise. *  x        - The x-coordinate of the basepoint (roughly the lower left corner) of the first letter. *  y        - The y-coordinate of the basepoint (roughly the lower left corner) of the first letter. *  string   - The string to render. * * Variant: *  - <gdImageStringFTEx> * * See also: *  - <gdImageString> */BGD_DECLARE(char *) gdImageStringFT (gdImage * im, int *brect, int fg, const char *fontlist,                                     double ptsize, double angle, int x, int y, const char *string){    return gdImageStringFTEx (im, brect, fg, fontlist,                              ptsize, angle, x, y, string, 0);}

从实现可以看出gdImageStringFT只是gdImageStringFTEx的一种特例.
函数传参中:

  • brect是指向8个元素大小的一维数组的指针,用来接受绘制文本后文本区域的左下/右下/右上/左上的坐标值.
  • fontlist 分号分割的字体文件(包含路径)名列表.
  • x/y 文字绘制的起始点坐标(左下为起始基准)
  • ptsize文字大小,用文字高度描述
  • string 绘制的文本,注意函数内使用’\0’作为文本结束的标志,在使用例如ngx_string_t等数据时注意处理转换;支持utf-8中文字符的渲染,若渲染出席乱码方块,查看下选择的字体库是否支持中文.

使用示例

GD库中的一个使用测试示例:

#include "gd.h"#include <stdio.h>#include <stdlib.h>#include <math.h>#include "gdtest.h"#define PI 3.141592#define DELTA (PI/8)static int EXPECT[16][8] = {    {498, 401, 630, 401, 630, 374, 498, 374},    {491, 364, 613, 313, 602, 288, 481, 338},    {470, 332, 563, 239, 544, 219, 451, 312},    {438, 310, 488, 189, 463, 178, 412, 300},    {401, 303, 401, 171, 374, 171, 374, 303},    {365, 310, 314, 188, 289, 199, 339, 320},    {334, 331, 241, 238, 221, 257, 314, 350},    {313, 362, 192, 312, 181, 337, 303, 388},    {306, 398, 174, 398, 174, 425, 306, 425},    {313, 433, 191, 484, 202, 509, 323, 459},    {333, 463, 240, 556, 259, 576, 352, 483},    {363, 484, 313, 605, 338, 616, 389, 494},    {398, 490, 398, 622, 425, 622, 425, 490},    {432, 483, 483, 605, 508, 594, 458, 473},    {461, 464, 554, 557, 574, 538, 481, 445},    {481, 435, 602, 485, 613, 460, 491, 409},};int main(){    char *path;    gdImagePtr im;    int black;    double cos_t, sin_t;    int x, y, temp;    int i, j;    int brect[8];    int error = 0;    FILE *fp;    /* disable subpixel hinting */    putenv("FREETYPE_PROPERTIES=truetype:interpreter-version=35");    path = gdTestFilePath("freetype/DejaVuSans.ttf");    im = gdImageCreate(800, 800);    gdImageColorAllocate(im, 0xFF, 0xFF, 0xFF); /* allocate white for background color */    black = gdImageColorAllocate(im, 0, 0, 0);    cos_t = cos(DELTA);    sin_t = sin(DELTA);    x = 100;    y = 0;    for (i = 0; i < 16; i++) {        if (gdImageStringFT(im, brect, black, path, 24, DELTA*i, 400+x, 400+y, "ABCDEF")) {            error = 1;            goto done;        }        for (j = 0; j < 8; j++) {            if (brect[j] != EXPECT[i][j]) {                gdTestErrorMsg("(%d, %d) (%d, %d) (%d, %d) (%d, %d) expected, but (%d, %d) (%d, %d) (%d, %d) (%d, %d)\n",                       EXPECT[i][0], EXPECT[i][1], EXPECT[i][2], EXPECT[i][3],                       EXPECT[i][4], EXPECT[i][5], EXPECT[i][6], EXPECT[i][7],                       brect[0], brect[1], brect[2], brect[3],                       brect[4], brect[5], brect[6], brect[7]);                error = 1;                goto done;            }        }        gdImagePolygon(im, (gdPointPtr)brect, 4, black);        gdImageFilledEllipse(im, brect[0], brect[1], 8, 8, black);        temp = (int)(cos_t * x + sin_t * y);        y = (int)(cos_t * y - sin_t * x);        x = temp;    }    fp = gdTestTempFp();    //fp = fopen("/tmp/stringft.png","wb");    gdImagePng(im, fp);    fclose(fp);done:    gdImageDestroy(im);    gdFontCacheShutdown();    free(path);    return error;}

以上这段测试代码实现的功能:

  • 将以(400,400)处为圆心,100为半径的圆八等分,以等分点为起始点,沿着半径延长线绘制文字”ABCDEF”.
  • 文字外围绘制边框. - 文本绘制起始点处绘制实心椭圆

代码中:

  • gdImagePolygon为无填充多边形绘制函数,这里绘制了一个四边形矩形.
  • gdImageFilledEllipse (gdImagePtr im, int mx, int my, int w, int h, int c) 为绘制实心椭圆, 其中mx,my为中心坐标(示例中brect[0], brect[1]即文本绘制参考起始点),w为半长轴,h为半短轴(这里均为8,即绘制圆),c为颜色.

测试示例的绘制的最终效果如下:

文本绘制

原创粉丝点击