iMagicについて
ImageMagickのPECL版について紹介します。ImageMagickは画像編集の全般が行える強力なツールです。
PECL版でも殆どの事が行えるようになっています。
画像処理のエフェクト関連はかなり充実している印象があります。
東北大学のページで詳しく紹介されています。
エフェクトや主な画像処理に関しては、付属のexamplesが大量にあるのでそれを参照ください。
PHP-Imagick Exemples
ここではGIFアニメについてのサンプルを紹介いたします。
GIFアニメサンプル
FreeBSDでのインストール
PHPはすでにインストールされているものとします。セットアップ環境が直接インターネットに接続できる場合以下のコマンドを入力します。
pecl install -f imagick接続できない場合はここから最新のパッケージをダウンロードします。
(2006/05/16現在:imagick-0.9.11.tgz)
pecl install imagick-0.9.11.tgz私がさくらインターネットで行った例
$ pecl download imagick
$ tar xzvf imagick-0.9.11.tgz
$ cd imagick-0.9.11
$ phpize
Configuring for:
PHP Api Version: 20020918
Zend Module Api No: 20020429
Zend Extension Api No: 20050606
Cannot find autoconf. Please check your autoconf installation and the $PHP_AUTOC
ONF
environment variable is set correctly and then rerun this script.$ setenv PHP_AUTOCONF /usr/local/bin/autoconf213
$ setenv PHP_AUTOHEADER /usr/local/bin/autoheader213環境変数を設定していなかったので直接以下を実行
$ /usr/local/bin/autoconf213
$ /usr/local/bin/autoheader213
$ ./configure
何か色々でる……
$ make
----------------------------------------------------------------------
Libraries have been installed in:
/home/rakuto/PEAR/sources/imagick-0.9.11/modules
If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the `LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the `LD_RUN_PATH' environment variable
during linking
- use the `-Wl,--rpath -Wl,LIBDIR' linker flag
See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
Build complete.
(It is safe to ignore warnings about tempnam and tmpnam).root権限が無いのでMakfileの EXTENSION_DIR を書き換え。
$ make install簡易クラスのソースコード
/** * アニメGIF作成クラス * * @author 高橋 裕志郎 <yujiro@rakuto.net> * @package RKT_animated * @access public * @version 1.1 */ class RKT_animated { /** * iMagickハンドル * @var resource */ var $animated = null; /** * ソースサイズ * @var array */ var $srcsize = null; /** * コンストラクタ * * @access public * @param string $source * @return void */ function RKT_animated() { if (!extension_loaded('imagick')) { $prefix = (PHP_SHLIB_SUFFIX == 'dll') ? 'php_' : ''; dl($prefix . 'imagick.' . PHP_SHLIB_SUFFIX); } /* アニメGIF用の空ハンドルを用意 */ $this->animated = imagick_newimagelist(); if (imagick_iserror($this->animated)){ $reason = imagick_failedreason($this->animated); $description = imagick_faileddescription($this->animated); error_log('imagick_newimagelist() failed!'."\t".'Reason: '.$reason."\t". 'Description: '.$description."\r\n", 3, ERROR_LOG_FILE); return false; } } /** * ベース画像の情報を設定 * * @access private * @param resource $handle iMagickハンドル * @return boolean 真偽値 */ function set_baseinfo(&$handle) { $this->srcsize['width'] = imagick_getwidth($handle); if (!$this->srcsize['width']){ $reason = imagick_failedreason($handle); $description = imagick_faileddescription($handle); error_log('imagick_getwidth() failed!'."\t".'Reason: '.$reason."\t". 'Description: '.$description."\r\n", 3, ERROR_LOG_FILE); return false; } $this->srcsize['height'] = imagick_getheight($handle); if (!$this->srcsize['height']){ $reason = imagick_failedreason($handle); $description = imagick_faileddescription($handle); error_log('imagick_getheight() failed!'."\t".'Reason: '.$reason."\t". 'Description: '.$description."\r\n", 3, ERROR_LOG_FILE); return false; } return true; } /** * 対象画像ファイルのリサイズ値を取得 * * @access public * @param resource $handle iMagickハンドル * @param integer $width 幅の最大値 * @param integer $height 高さの最大値 * @return array リサイズした幅と高さ */ function getResize(&$handle, $width, $height) { $srcsize = array( 'width'=> 0, 'height'=> 0, ); $srcsize['width'] = imagick_getwidth($handle); if (!$srcsize['width']){ $reason = imagick_failedreason($handle); $description = imagick_faileddescription($handle); error_log('imagick_getwidth() failed!'."\t".'Reason: '.$reason."\t". 'Description: '.$description."\r\n", 3, ERROR_LOG_FILE); return false; } $srcsize['height'] = imagick_getheight($handle); if (!$srcsize['height']){ $reason = imagick_failedreason($handle); $description = imagick_faileddescription($handle); error_log('imagick_getheight() failed!'."\t".'Reason: '.$reason."\t". 'Description: '.$description."\r\n", 3, ERROR_LOG_FILE); return false; } $w_scale = $width / $srcsize['width']; $h_scale = $height / $srcsize['height']; /* 倍率の決定 */ $scale = ($w_scale < $h_scale)?$w_scale:$h_scale; /* 縮小のみは以下を実行 */ $scale = ($scale >= 1.0)?1:$scale; return array( 'width'=> intval($srcsize['width'] * $scale), 'height'=> intval($srcsize['height'] * $scale), ); } /** * フレームの追加 * * @access public * @param string $source * @return boolean 真偽値 */ function addFreame($source) { /* 画像ファイルの読み出し */ $handle = imagick_readimage($source); if (imagick_iserror($handle)){ $reason = imagick_failedreason($handle); $description = imagick_faileddescription($handle); error_log('handle failed!'."\t".'Reason: '.$reason."\t". 'Description: '.$description."\r\n", 3, ERROR_LOG_FILE); return false; } /* 基準サイズが設定されているか? */ if (!is_array($this->srcsize)){ if (!$this->set_baseinfo($handle)){ error_log('set_baseinfo() failed!'."\t".'Reason: '. print_r($this->animated, true)."\r\n", 3, ERROR_LOG_FILE); return false; } } /* 基準の画像サイズを基にリサイズ */ $resize = $this->getResize($handle, $this->srcsize['width'], $this->srcsize['height']); if (!imagick_resize($handle, $resize['width'], $resize['height'], IMAGICK_FILTER_UNKNOWN, 0)){ $reason = imagick_failedreason($handle); $description = imagick_faileddescription($handle); error_log('imagick_resize() failed!'."\t".'Reason: '.$reason."\t". 'Description: '.$description."\r\n", 3, ERROR_LOG_FILE); return false; } /* 画像フレームのリストを追加する */ if (!imagick_pushlist($this->animated, $handle)){ $reason = imagick_failedreason($this->animated); $description = imagick_faileddescription($this->animated); error_log('imagick_pushlist() failed!'."\t".'Reason: '.$reason."\t". 'Description: '.$description."\r\n", 3, ERROR_LOG_FILE); return false; } return true; } /** * 画像ファイルを保存する * * @access public * @param string $filename ファイル名 * @return boolean 真偽値 */ function saveImage($filename) { if (imagick_iserror($this->animated)){ $reason = imagick_failedreason($this->animated); $description = imagick_faileddescription($this->animated); error_log('var animated failed!'."\t".'Reason: '.$reason."\t". 'Description: '.$description."\r\n", 3, ERROR_LOG_FILE); return false; } /* GIFに指定(拡張子が指定してあれば不要) */ imagick_convert($this->animated, 'GIF' ); /* 画像をファイルに書き出す */ if (!imagick_writeimage($this->animated, $filename)) { $reason = imagick_failedreason($this->animated); $description = imagick_faileddescription($this->animated); error_log('imagick_writeimage() failed!'."\t".'Reason: '.$reason."\t". 'Description: '.$description."\r\n", 3, ERROR_LOG_FILE); return false; } return true; } } // RKT_animated
実行ソースコード
require_once './rkt_animated.php'; define('ERROR_LOG_FILE', 'error.log'); _main(); // 実行関数 // ------------------------------------------------ // 実行関数 // 引数 なし // 戻り値 なし // ------------------------------------------------ function _main() { if (empty($_POST['manip'])){ return ; } $objimg = new RKT_animated(); for ($row=0; $row<6; $row++){ if (isSet($_FILES['frame'.$row])) { if (!empty($_FILES['frame'.$row]['tmp_name'])) { $objimg->addFreame($_FILES['frame'.$row]['tmp_name']); } } } $objimg->saveImage('./animated.gif'); }
<form name="imagick" method="post" enctype="multipart/form-data" action="<?php echo $_SERVER['PHP_SELF']; ?>"> <table cellpadding="4" cellspacing="1"> <tr> <td>フレーム1</td><td><input type="file" name="frame0" /></td> </tr> <tr> <td>フレーム2</td><td><input type="file" name="frame1" /></td> </tr> <tr> <td>フレーム3</td><td><input type="file" name="frame2" /></td> </tr> <tr> <td>フレーム4</td><td><input type="file" name="frame3" /></td> </tr> <tr> <td>フレーム5</td><td><input type="file" name="frame4" /></td> </tr> <tr> <td>フレーム6</td><td><input type="file" name="frame5" /></td> </tr> <tr> <td colspan="2"><input type="submit" name="manip" value="送信" /></td> </tr> </table> </form><br /> <img src="./animated.gif" />
