とらりもんHOME  Index  Search  Changes  Login

gd

2003/08/16 西田顕郎

  • Note: 以下、プロンプトを$で表すので、以下の説明で、$は打ち込まなくてよい。
  • Note: #は管理者(ルート)のプロンプトを表す。これも打ち込まなくてよい。

gdはjpegとかpngの画像をいろいろいじるためのライブラリで、netpbmよりもドキュメントがよく整備されているとかで、C言語などで画像をいじるプログラムを自作するのに便利である。RedHatなどのLinuxのディストリビューションにはデフォルトで入ってくるようだ(試しに $ rpm -q gd などと打ってみてください)。

とりあえずここのサンプルプログラムをgdtest.cのような名前で保存して、

$ gcc gdtest.c -lgd

とやってみる。うまくコンパイルができて, $./a.outとすると、test.pngとtest.jpgという2つの画像ファイルができているはず。それぞれ、黒地に白線が左上から右下に引かれた単純な絵で、$ ee test.pngなどで確認。

jpeg画像をいくつかの矩形領域に分割するプログラム: divjpg_.c

/* divjpg_.c
* Dividing a jpeg image to several parts.
* 2003/8/16 Kenlo Nishida
* compile: $ gcc divjpg_.c -lgd
* note: This program uses "gd" library <http://www.boutell.com/gd/>
*/

#include "gd.h"
#include <stdio.h>
# define STRN 256

void errorout()
{printf("divjpg_.c : Dividing a jpeg image to several parts.\n");
printf("Usage:   $ divjpg_ tile_nx tile_ny fnin.jpg quality\n"); 
printf("      tile_nx, tile_ny (int) : Number of tiles in x and y directions respectively.\n");
printf("      fnin.jpg (string) : file name of the input jpeg file.\n");
printf("      quality (int; 0-95) : (optional) quality of the output jpeg images.\n");
printf("  Default quality is set to -1 which is managed in the gd library.\n");
printf("Example: $ divjpg_ 2 2 input.jpg\n");
printf("Copyright: Kenlo Nishida, distributable under GPL.\n");
exit(0);
}

int main(int argc, char **argv) 

{
char fnin[STRN], fnhead[STRN], fnout[STRN];
gdImagePtr imin, imout;
FILE *jpegin, *jpegout;
int tile_nx=0, tile_ny=0;
int i=0, j=0;
int quality=-1;

if (argc<4) errorout();
tile_nx=atoi(argv[1]);
tile_ny=atoi(argv[2]);
strncpy(fnin, argv[3], STRN);
strncpy(fnhead, argv[3], STRN);
fnhead[strlen(fnhead)-4]=0;           /* cut extention (.jpg) from the file name */
if (argc>4) quality=atoi(argv[4]);
if (quality>95) quality=95;
if (quality<0) quality=-1;

if (!(jpegin=fopen(fnin, "rb")))
 {printf("File %s was not found\n", fnin);
  errorout();
 }

imin = gdImageCreateFromJpeg(jpegin);
fclose (jpegin);

imout = gdImageCreateTrueColor(imin->sx/tile_nx, imin->sy/tile_ny);

for (j=0; j<tile_ny; j++)
       for (i=0; i<tile_nx; i++)
               {gdImageCopy(imout, imin, 
                       0,                 0, 
                       i*imin->sx/tile_nx, j*imin->sy/tile_ny, 
                       imin->sx/tile_nx,   imin->sy/tile_ny);
                sprintf(fnout, "%s_%d_%d.jpg", fnhead, i, j);
                jpegout = fopen(fnout, "wb");
                gdImageJpeg(imout, jpegout, quality);
                fclose(jpegout);
               }

gdImageDestroy(imin);
gdImageDestroy(imout);
}

jpeg画像を任意の角度で回転するプログラム: rotjpg_.c ソース

/* rotjpg_.c
* Rotating a jpeg image.
* 2003/8/17 Kenlo Nishida
* compile: $ gcc rotjpg_.c -lgd -lm
* note: This program uses "gd" library <http://www.boutell.com/gd/>
*/

#include "gd.h"
#include <stdio.h>
#include <math.h>
# define PI 3.14159265

void errorout()
{printf("rotjpg_.c : Rorating a jpeg image.\n");
printf("Usage:\n        $ rotjpg_ angle quality <src_image.jpg > out_image.jpg\n\n"); 
printf("  angle: (optional) Rotation angle in degree (integer). Default is set to 90.\n");
printf("  quality: (optional) Quality of the output image (integer; -1 - +95). defaul is set to -1 (system optimum).\n");
printf("Example: $ rotjpg_ input.jpg\n");
printf("Copyright: Kenlo Nishida, distributable under GPL.\n");
exit(0);
}

int main(int argc, char **argv) 

{
gdImagePtr imin, imout;
int angle=90;
int quality=-1;
int W=0, H=0, W1=0, H1=0, W2=0, H2=0;

if (argc==1) errorout();
if (argc>1) angle=atoi(argv[1]);
if (argc>2) quality=atoi(argv[2]);
if (quality>95) quality=95;
if (quality<0) quality=-1;

imin = gdImageCreateFromJpeg(stdin);

W1=abs(  imin->sx * cos((float)angle*PI/180.0) - imin->sy * sin((float)angle*PI/180.0)  );
H1=abs(  imin->sx * sin((float)angle*PI/180.0) + imin->sy * cos((float)angle*PI/180.0)  );
W2=abs(  imin->sx * cos((float)angle*PI/180.0) + imin->sy * sin((float)angle*PI/180.0)  );
H2=abs(  imin->sx * sin((float)angle*PI/180.0) - imin->sy * cos((float)angle*PI/180.0)  );
if (W1>W2) W=W1; else W=W2;
if (H1>H2) H=H1; else H=H2;
imout = gdImageCreateTrueColor(W, H);

gdImageCopyRotated(imout, imin, W/2, H/2, 0, 0, imin->sx, imin->sy, angle);
gdImageJpeg(imout, stdout, quality);

gdImageDestroy(imin);
gdImageDestroy(imout);
}

注意! バージョン1.8.4-9と2.0以上の相違点 下位バージョンでうまく出力されていたJPEG画像が、バージョン2以上では単色の妙な画像になってしまうことがある。これはgdImageCreate関数が、true color画像をうまく扱えていないため。バージョン2以上ではgdImageCreate関数のかわりに、gdImageCreateTrueColor関数を使えばOK。

バージョンアップの方法 RedHat9でもまだバージョン1.8.4しか入っていない。ここは、ソースをコンパイルして対応する。

まず/etc/ld.so.confに/usr/local/libを追加。その後、

  1. rpm -e --nodeps gd
  2. rm /usr/lib/libgd.a
  3. rm /usr/lib/libgd.so

$ mkdir ~/tmp; cd ~/tmp $ wget http://www.boutell.com/gd/http/gd-2.0.15.tar.gz $ tar zxvf gd-2.0.15.tar.gz $ cd gd-2.0.15 $ ./configure $ make

  1. make install
  2. /sbin/ldconfig
Last modified:2018/11/04 17:47:20
Keyword(s):
References:[とらりもんHOME]