とらりもん - 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
*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