ImageMagickについて
メモリ上の画像をImageMagickによって加工する方法について紹介します。ImageMagickは画像編集の全般が行える強力なツールです。
東北大学のページで詳しく紹介されています。
エフェクトや主な画像処理に関しては、以下にて大量に紹介されているのでそれを参照ください。
Examples of ImageMagick Usage
ここではGIFアニメについてのサンプルといくつかのエフェクトを紹介いたします。
GIFアニメサンプル
エフェクトサンプル
rkt_ImageMagick
すでに紹介したPECL版のiMagickが使いにくいので、直接ImageMagickを使用しました。exec()関数により、ImageMagickのコマンドを呼び出してもよいのですが今回は以下の関数を使用してみました。
proc_open()
passthru()
fpassthru()
proc_open()関数を使うことでpipe処理によりメモリ上の画像データを加工・表示することが可能になります。
passthru()やfpassthru()関数はバイナリデータを扱うのでデータ読み込み用に使用しています。
この関数はともに読み込みデータを出力してしまうので、ob_get_contents()関数によりデータを取得します。
ソースコードが1500行近くとバカ長いのでソースの中身は以下を参照ください。
rkt_imagemagick.php
ImageMagick操作クラス概要
/** * ImageMagick操作クラス * * @author 高橋 裕志郎 <yujiro@rakuto.net> * @package RKT_imgManipulation * @access public * @version 1.1 */ class RKT_imagemagick { /** * 画像ファイル名 * @var string */ var $filename = ''; /** * 画像情報 * @var array */ var $infos = array(); /** * 画像のバイナリ情報 * @var binary */ var $buffer = null; /** * コンストラクタ * * @access public * @param string $source * @return void */ function RKT_imagemagick($filename) { if (!file_exists ($filename)){ return ; } $this->filename = $filename; $this->readimage($this->filename); } /** * 画像情報をバッファに格納 * * @access private * @return boolean */ function readimage($filename) { $this->filename = $filename; if (!file_exists ($this->filename)){ return false; } $this->set_info(); /* ファイルの中身を取得 */ $handle = fopen($this->filename, 'rb'); if (!is_resource($handle)) { return false; } $this->buffer = fread($handle, filesize($this->filename)); fclose($handle); return true; } /** * コマンドの直接実行 * * @access public * @param string $command コマンド名 * @param string $param パラメータ * @return boolean */ function direct($command, $param) { $command = '"'.RKT_IMAGEMAGICK_PATH.$command.'" '. $param.' '.$this->filename; ob_start(); passthru($command); $result = ob_get_contents(); ob_end_clean(); return $result; } /** * コマンドの実行 * * @access public * @param string $command コマンド名 * @param string $param パラメータ * @return boolean */ function command($command, $param) { $command = '"'.RKT_IMAGEMAGICK_PATH.$command.'" '.$param; $inout = substr_count($param, ':-'); $descriptorspec = array( 0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('file', ERROR_LOG_FILE, 'a') ); $pipes = array(); $process = proc_open($command, $descriptorspec, $pipes); if (!is_resource($process)) { return false; } if ($inout == 2){ fwrite($pipes[0], $this->buffer); fclose($pipes[0]); } ob_start(); fpassthru($pipes[1]); $this->buffer = ob_get_contents(); ob_end_clean(); fclose($pipes[1]); proc_close($process); return true; } /** * フィル情報の取得 * * @access public * @return object */ function set_info() { $format = array( 'so'=> '"%m:%f:%w:%h;"', 'dll'=> '%m:%f:%w:%h;', ); $param = '-format '; $param .= $format[PHP_SHLIB_SUFFIX].' '; $result = $this->direct('identify', $param); $row = explode(';', $result); if (empty($row[0])){ $this->info = array('error'=>1); return ; } $info = explode(':', $row[0]); $this->infos = array( 'type'=> $info[0], 'format'=> strtolower($info[0]), 'name'=> $info[1], 'width'=> $info[2], 'height'=> $info[3], ); } } // RKT_imagemagick
実行ソースコード
define('RKT_IMAGEMAGICK_PATH','/usr/local/bin/'); define('ERROR_LOG_FILE','error.log'); include_once './rkt_imagemagick.php'; // ------------------------------------------------ // 実行関数 // 引数 なし // 戻り値 なし // ------------------------------------------------ function _main() { $objimg = new RKT_imagemagick('image.jpg'); $width = 100; $height = 100; $command = 'convert'; $param = '-resize '; $param .= $width.'x'.$height.' '; $param .= $objimg->infos['format'].':- '.$objimg->infos['format'].':-'; $objimg->command($command, $param); $objimg->save('resize.jpg'); } _main(); // 実行関数
