とらりもんHOME  Index  Search  Changes  Login

とらりもん - gd Diff

  • Added parts are displayed like this.
  • Deleted parts are displayed like this.

2003/08/16 西田顕郎

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

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

とりあえず[[ここ|https://boutell.com/gd/manual2.0.15.html#basics]]のサンプルプログラムを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を追加。その後、

# rpm -e --nodeps gd
# rm /usr/lib/libgd.a
# 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
# make install
# /sbin/ldconfig