使用GDlib在圖片上繪製文字
阿新 • • 發佈:2019-02-11
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/ ./
make
make 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為顏色.
測試示例的繪製的最終效果如下: