PHPでGDを使おう

GDとは

GDライブラリを使うとPHPでJPEG,PNG,GIFなどの画像処理ができます。

これはたいへん便利で、たとえば、私の会社では製品デザインの画像データベースを作って、その画像を縮小して一覧表示したり、製品名から検索したりできるようにしてあります。このシステムもLinux+Apache+MySQL+PHPで作りました。

また、大量の画像ファイルのサイズを変えたり、タイトルを入れたりするような機械的処理だけですとPHPでは一括処理ができるのでレタッチ・ソフトを使うよりもすばやく簡単にできることもよくあります。


GDを使う準備

PHP4.2以下でGDを使うためには別途にGDライブラリをインストールする必要がありました(これがなかなか難しいんですよね)。ですが、PHP4.3以降ではGD互換ライブラリがPHPに同梱されるようになったので簡単に利用できます。ですから、ここではPHP4.3.3を元に書きます。

Windows版での準備

php.iniを次のように変更します。
;extension=php_gd2.dll
  ↓ コメントをはずします
extension=php_gd2.dll

変更したら「スタート/プログラム/プログラム/Apache HTTP Server/Control Apache Server/Restart」を選択して、Apacheを再起動してください。これでGDが利用できます。

Linux版での準備

私はいつもソースからインストールするので ./configure のオプションで --with-gd の指定をしていればすでに利用できるようになっています。

GDが利用できるか確認

phpinfo()で「GD Support」が「enabled」になっているか確認してください。こうなっていればGDが利用できます。


画像処理の具体例 1

画像ファイルをアップロードして、その画像を縮小後にブラウザへ表示するサンプルです。このプログラムはWindows、Linuxのどちらでも動作します。

<?php

// 縮小後の横サイズ。縦サイズは元の画像と縦横比が同じになるように調節する
define(ResizeX, 300);

//============================================================================

// JPEGファイルがアップロードされたか?
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
	if (is_uploaded_file($_FILES['UpFile']['tmp_name'])) {
		if ( mb_strpos($_FILES['UpFile']['type'], 'jpeg') ) {

			// JPEG画像を読み込む
			$im_inp = ImageCreateFromJPEG($_FILES['UpFile']['tmp_name']);
			$ix = ImageSX($im_inp);    // 読み込んだ画像の横サイズを取得
			$iy = ImageSY($im_inp);    // 読み込んだ画像の縦サイズを取得
			$ox = ResizeX;			   // サイズ変更後の横サイズ
			$oy = ($ox * $iy) / $ix;   // サイズ変更後の縦サイズ

			// サイズ変更後の画像データを生成
			$im_out = ImageCreateTrueColor($ox, $oy);
			ImageCopyResized($im_out, $im_inp, 0, 0, 0, 0, $ox, $oy, $ix, $iy);

			// 画像の表示
			header("Content-type: image/jpeg");
			header("Cache-control: no-cache");
			ImageJPEG($im_out);

			// メモリーの解放
			ImageDestroy($im_inp);
			ImageDestroy($im_out);
			exit;
		}
	}
}
else {
?>
<html>
<head>
<title>画像の縮小表示</title>
</head>

<body>
<form enctype="multipart/form-data" method=post action="/php/gd/" target=_brank>
<h1 align=center>画像の縮小表示</h1>
<p>
	<input type=file name=UpFile size=60>
	<input type=submit value=" 縮小表示 ">
</p>

</form>
</body>
</html>
<?php
}
?>

画像処理の具体例 2

ここでは、コマンドライン版PHPを利用してディレクトリに保存してあるすべてのJPEGファイルを縮小して別ファイルで保存する例を書きます。簡単なプログラムなのでソースを見ていただければわかると思います。このプログラムもWindows、Linuxのどちらでも動作します。

<?php
// ここにJPEGファイルを保存してあるディレクトリを指定しておく
define(ScanDir, 'C:/My Pictures');

// 縮小後の画像を保存するディレクトリを指定(ScanDirと同じにすることも可能)
define(SaveDir, 'C:/My Pictures2');

// 縮小後の横サイズ。縦サイズは元の画像と縦横比が同じになるように調節する
define(ResizeX, 300);

// 縮小後のファイル名(元のファイル名にこの文字列が付加つれる)
define(NameValue, ('_' . ResizeX));

//============================================================================
// ディレクトリ一覧を取得して、$dirs[]の配列に保存する
$dirs[0] = ScanDir;
for ($i = 0; $i < count($dirs); $i++) {
	GetDir($dirs[$i]);
}

// サブ・ディレクトリを取得して$dirs[]に要素を追加
function GetDir($path) {
	global $dirs;

	if (!($dir = @opendir($path))) return;
	while ($fname = readdir($dir)) {
		if ($fname != '.' && $fname != '..') {
			if (is_dir("$path/$fname")) {
				$dirs[count($dirs)] = "$path/$fname";
			}
		}
	}
	closedir($dir);
}

// すべての画像を縮小してファイルへ保存
for ($i = 0; $i < count($dirs); $i++) {
	if ($dir = @opendir($dirs[$i])) {
		// ディレクトリ内の全JPEGファイルを取得する
		while ($fname = readdir($dir)) {
			if ($fname != '.' && $fname != '..') {
				if (is_file($dirs[$i] . "/$fname")) {
					$ex = explode('.', $fname);
					$ext = strtolower($ex[count($ex) - 1]);
					if ( count($ex) > 1 && ($ext == 'jpg' || $ext == 'jpeg') ) {
						// JPEG画像のサイズを変更
						convertJpeg($dirs[$i], $fname);
					}
				}
			}
		}
		closedir($dir);
	}
}

// 指定したディレクトリ内の$fnameというファイル名のJPEG画像のサイズを変更
function convertJpeg($dirname, $fname) {
	global $jpg;   // 過去に生成したJPEG画像の配列

	$path = "$dirname/$fname";

	// このプログラム自身で過去に生成したファイルならば処理しない
	for ($i = 0; $i < count($jpg); $i++)
		if ($jpg[$i] == $path) return;

	// JPEG画像を読み込む
	$im_inp = ImageCreateFromJPEG($path);

	$ix = ImageSX($im_inp);    // 読み込んだ画像の横サイズを取得
	$iy = ImageSY($im_inp);    // 読み込んだ画像の縦サイズを取得
	$ox = ResizeX;			   // サイズ変更後の横サイズ
	$oy = ($ox * $iy) / $ix;   // サイズ変更後の縦サイズ

	// サイズ変更後の画像データを生成
	$im_out = ImageCreateTrueColor($ox, $oy);
	ImageCopyResized($im_out, $im_inp, 0, 0, 0, 0, $ox, $oy, $ix, $iy);

	// 保存するディレクトリを生成
	$outdir = SaveDir . "/" . mb_substr($dirname, mb_strlen(ScanDir));
	if (!is_dir($outdir))
		mkdir($outdir);

	// サイズ変更後の画像をファイルへ保存
	$ex = explode('.', $fname);
	$outfile = $outdir . "/" . $ex[0] . NameValue . "." . $ex[1];
	ImageJPEG($im_out, $outfile);

	// メモリーの解放
	ImageDestroy($im_inp);
	ImageDestroy($im_out);
	$jpg[count($jpg)] = $outfile;
}
?>

画像処理の具体例 3

このサンプルでは画像に文字列を挿入してみます。

<?php
// フォント・ファイルは環境によっては変更が必要
$Font = "/usr/share/fonts/alias/TrueType/mincho-mr-jisx0201.1976-0.ttf";
$FontSize = 20;

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
	$im = ImageCreate($FontSize * mb_strlen($_POST['iText']) * 1.4, $FontSize * 2);
	ImageFill($im, 0, 0, ImageColorAllocate($im, 0x30, 0x30, 0x30));
	$x = 5;
	$y = $FontSize * 1.5;
	mt_srand(date('His'));
	for ($i = 0; $i < mb_strlen($_POST['iText']); $i++) {
		$chr = mb_convert_encoding(mb_substr($_POST['iText'], $i, 1), "UTF-8");
		$Color = ImageColorAllocate($im, mt_rand(80,255), mt_rand(80,255), mt_rand(80,255));
		$box = ImageTTFText($im, $FontSize, 0, $x, $y, $Color, $Font, $chr);
		$x = $box[2];
	}
	header("Content-type: image/png");
	header("Cache-control: no-cache");
	ImagePNG($im);
	imagedestroy($im);
	exit;
}
?>
<html>
<head>
<title>GD テスト</title>
</head>

<body>
<form method=post action="<?php echo $_SERVER['REQUEST_URI'] ?>" target=_blank>
<h1 align=center>GD テスト</h1>
<p>何か、漢字を含む文字列を入力してください</p>
<p>
	<input type=text name=iText size=60>
	<input type=submit value=" GD表示 ">
</p>

</form>
</body>
</html>

私の環境では、このプログラムはWindows版PHPでは漢字が文字化けします。Linux版PHPでは問題なく動作するようです。色々調べたところ、どうやらフォント・ファイルに問題があるようで、OpenTypeフォントのみうまく表示されるようです。

上記2つはライセンス・フリーなのでこの2種類のOpenTypeフォントで動作確認したところ、漢字も化けずにWin版PHPで表示できました。

PHPのページ TOPへ戻る

Copyright©2001-2019 釣ったよ! All Right Reserved.    sg@tsuttayo.jpn.org