FuelPHPのImageクラス

今日は、FuelPHPのImageクラスについて調べてみたいと思います。ドキュメントによると『FuelPHPのImageクラスは、簡単にリサイズ、トリミングなど、画像に共通の操作を追加するために使用されています。』と記述されています。そして、制限事項にGDライブラリには透明処理に欠陥があるようなことが書いてあります。その辺のことを念頭に入れながら使用していくことにしましょう。

環境設定

1. Imageクラスの設定ファイルは、core/configフォルダのimage.phpをapp/configフォルダにコピーしてから使用します。それでは、コピーしたimage.phpの中身を見てみましょう。簡単に注釈を入れてみました。

app/config/image.php

<?php
 return array(
 //ドライバの指定(使用可能ドライバはgd, imagemagick or imagick)
 'driver' => 'gd',
//背景色のセット(nullの場合透明色がセット)
 'bgcolor' => null,
//透かし文字の透明度のセット(0~100)
 'watermark_alpha' => 75,
//画質のセット
 'quality' => 100,
//画像の拡張子の指定(nullの場合、元の拡張子を引き継ぐ)
 'filetype' => null,
//imagemagickの保管場所(先頭に/が必要)
 'imagemagick_dir' => '/usr/bin/',
//編集中の画像の一時保管場所の指定
 'temp_dir' => APPPATH.'tmp'.DS,
//競合を避けるためにイメージに付与する文字
 'temp_append' => 'fuelimage_',
//保存や出力後(save(), save_pa(), output())にクリアするかどうかの指定
 'clear_queue' => true,
//保存や出力後に元イメージをリロードする場合はfalse、修正後の画像をキープする場合はtureを指定します。
 'persistence' => false,
//デバッグの使用するかどうかを指定します。
 'debug' => false,
//設定をプリセットにセットしておけば、制御された操作を呼び出すことができます。
 'presets' => array(
/*設定例
 *
 * 設定値はここでは、現在の設定を上書きすることに注意してください。
 *
 * ドライバはここで変更することはできません。
 */
 'example' => array(
 'quality' => 100,
 'bgcolor' => null,
 'actions' => array(
 array('crop_resize', 200, 200),
 array('border', 20, "#f00"),
 array('rounded', 10),
 array('output', 'png')
 )
 )
 )
 );

Imageクラスのメソッド

2. Imageクラスのメソッドを例題を見ながら調べてみたいと思います。

forge($configの配列)

このメソッドは、新しいイメージドライバーのインスタンスを作成します。

//デフォルト(環境ファイルに基づいた)インスタンスの作成
$image=Image::forge();
// オプションの環境設定を配列で指定します
$image=Image::forge(array(
'quality'=>80
));
//チェーンメソッドで指定できます 
$image->load('image.png')->output('image.jpeg');

config(パラメータ名,値=null)

このメソッドは、configファイルの指定のパラメータの値を変更します。

//背景色を'#f00'に変更 
Image::load('finemane.gif)->config('bgcolor','#f00') 
//配列で指定することも出来ます
Image::load('filename.gif)->config(array(
'bgcolor'=>'#f00',
'quality'=>'80' ));

load(ファイル名,$return_data=false)

このメソッドは、編集のための画像をロードします。第2引数は、画像データを返すかどうかを指定します(GDでのみ動作)。 まず一番最初に躓いたのが、ロードするファイルの場所(パス)です。ドキュメントにはロードする画像のパスの記述が見つからなかったので、探し出すのに苦労しました。ロードのパスはドキュメントルート(public)直下でした。下記にsampleのコントローラとビューファイルを記述します。画像の保存場所は、asset/imgフォルダの下にsampleフォルダを作成して、保存することにしました。ビューファイルはデータのアップのみで使用しています。Imageデータをビューに渡すのが面倒だったので、コントローラでImageを表示しています。

app/classes/controller/sample.php

<?php
class Controller_Sample extends Controller{
 public function action_index(){
 //画像保存パスの設定
 $path='assets/img/sample/';
 //もしPOST送信されたら
 if (Input::method() == 'POST'){
 //Uploadクラスの設定
 $config=array(
 'path'=>DOCROOT.DS.$path,
 'auto_rename'=>true,
 'ext_whitelist'=>array('img','jpg','jpeg','gif','png'),
 );
 Upload::process($config);
 //ファイルアップロード検証がOKなら
 if(Upload::is_valid()){
 //画像を保存します
 Upload::save();
 $file=Upload::get_files(0);
 //ファイル情報の確認のため
 echo var_dump($file);
 //リサイズ画像名の作成(重複エラー処理)
 $new_file=$file['filename'].date('_ymdhis').$file['extension'];
 //今アップしたばかりの元画像データをロードして処理します
 $image=Image::load($path.$file['name']);
 //画像のリサイズ
 $image->crop_resize(200,200)->save($path.$new_file);
 //元画像の表示
 echo Asset::img('sample/'.$file['name']);
 //修正画像の表示 
 echo Asset::img('sample/'.$new_file); 
 }
 }
 return View::forge('sample/index');
 }
}

app/views/sample/index.php

<?php echo Form::open(array('name'=>'upload','enctype'=>'multipart/form-data','method'=>'post')); ?>
<?php echo Form::file('upload'); ?>
<?php echo Form::submit('submit', ' アップロード'); ?>
<?php echo Form::close(); ?>

ブラウザで確認してみます。味気ないですが、必要最低限のフォームしか作成していません。画像ファイルをアップロードしてみます。

元画像とリサイズ画像が表示されています。私の力不足だとは思いますが、このロードファイルのパスがどこにあるのかを探し出すだけでかなりの労力を要しました。

ちなみに画像は我が家の愛犬『蔵之介』です。宜しく。

保存フォルダも確認してみます。きちんと保存されているのが分かります。

crop($x1,$y1,$x2,$y2)

このメソッドは、座標やパーセンテージを指定して画像を作成します。画像の切り抜き方が分かるように簡単なプログラムを作成してみました。

app/classes/controller/sample.php

public function action_crop(){
 //もしPOST送信されたら
 if(Input::method() == 'POST'){
 $x1=Input::post('x1');
 $y1=Input::post('y1');
 $x2=Input::post('x2');
 $y2=Input::post('y2');
 //既にアップロード済みのファイルをロード
 Image::load('assets/img/sample/kuranosuke.jpg')
 ->crop($x1,$y1,$x2,$y2)
 ->output();
 }
 return View::forge('sample/crop');
 }

app/views/sample/crop.php

<meta charset="utf-8">
<?php echo Form::open(array('name'=>'crop','method'=>'post')); ?>
<table width="100%" border="0">
 <tr>
 <th scope="col">X1</th>
 <th scope="col">Y1</th>
 <th scope="col">X2</th>
 <th scope="col">Y2</th>
 </tr>
 <tr>
 <td align="center"><?php echo Form::input('x1'); ?></td>
 <td align="center"><?php echo Form::input('y1'); ?></td>
 <td align="center"><?php echo Form::input('x2'); ?></td>
 <td align="center"><?php echo Form::input('y2'); ?></td>
 </tr>
 <tr>
 <td colspan="4" align="center"><?php echo Form::submit('submit', 'CROP'); ?></td>
 </tr>
</table>
<?php echo Form::close(); ?>

ブラウザで確認してみます。適当に数字を入力してみます。元画像が1024×723の画像なので、上から3分の1を切り取ってみます。

画像が上から3分の1に切り取られているのがわかると思います。

resize(幅,高さ=null,$keepar=true,$pad=false)

このメソッドは、画像をリサイズします。幅又は、高さがnullの場合は、元の縦横比を保持します。第3引数が、trueの場合はオリジナルイメージと同じ縦横比を維持します。第4引数は今一不明です。このリサイズメソッドも視覚的に理解するために簡単なプログラムを作成してみました。

app/classes/controller/sample.php

public function action_resize(){
 //もしPOST送信されたら
 if(Input::method() == 'POST'){
 $w=Input::post('width');
 $h=Input::post('height');
 $k=(Input::post('keepar')=='true') ? true : false;
 $p=(Input::post('pad')=='true') ? true : false;
 Image::load('assets/img/sample/kuranosuke.jpg')
 ->resize($w,$h,$k,$p)
 ->output();
 }
 return View::forge('sample/resize');
 }

app/views/sample/resize.php

<meta charset="utf-8">
 <?php echo Form::open(array('name'=>'resize','method'=>'post')); ?>
 <table>
 <tr>
 <th>幅</th>
 <th>高さ</th>
 <th>keepar</th>
 <th>pad</th>
 </tr>
 <tr>
 <td><?php echo Form::input('width'); ?></td>
 <td><?php echo Form::input('height'); ?></td>
 <td><?php echo Form::select('keepar',"true",array("true"=>"true","false"=>"false")); ?></td>
 <td><?php echo Form::select('pad',"false",array("true"=>"true","false"=>"false")); ?></td>
 </tr>
 <tr>
 <td><?php echo Form::submit('submit', ' リサイズ'); ?></td>
 </table>
 <?php echo Form::close(); ?>

ブラウザで確認してみます。試しに第3引数をfalseに指定してみました。

こんな画像になってしまいました。皆さんも自分で試して下さい。

同じ数値で第3引数も、第4引数もtrueにすると、下のような画像になります。

crop_resize(幅,高さ=null)

このメソッドは、指定した幅と高さに合わせて切り取った画像をリサイズします。下記にコントローラとビューの例題を記述します。

app/classes/controller/sample.php

public function action_cropresize(){
 //もしPOST送信されたら
 if(Input::method() == 'POST'){
 $w=Input::post('width');
 $h=Input::post('height');
 Image::load('assets/img/sample/kuranosuke.jpg')
 ->crop_resize($w,$h)
 ->output();
 }
 return View::forge('sample/cropresize');
 }

app/views/sample/cropresize.php

<meta charset="utf-8">
 <?php echo Form::open(array('name'=>'cropresize','method'=>'post')); ?>
 <table>
 <tr>
 <th>幅</th>
 <th>高さ</th>
 </tr>
 <tr>
 <td><?php echo Form::input('width'); ?></td>
 <td><?php echo Form::input('height'); ?></td>
 </tr>
 <tr>
 <td><?php echo Form::submit('submit', ' クロップリサイズ'); ?></td>
 </table>
 <?php echo Form::close(); ?>

それでは、試しに幅200,高さ500と数字を入力してみます。数字の大きい方を基準として、数字の小さい方の両サイドをカットしてリサイズしています。

今度は、幅500,高さ200で入力しています。幅500は単にリサイズされているだけですが、高さは上下をカットしてリサイズされています。

rotate(回転度数)

このメソッドは、画像を時計回りに回転させます。このメソッドは特に難しくないと思いますが、一応コントローラとビューを下記に表示しておきます。

app/classe/controller/sample.php

public function action_rotate(){
 //もしPOST送信されたら
 if(Input::method() == 'POST'){
 $d=Input::post('degrees');
 Image::load('assets/img/sample/kuranosuke.jpg')
 ->rotate($d)
 ->output();
 }
 return View::forge('sample/rotate');
 }

app/views/sample/rotate.php

<meta charset="utf-8">
 <?php echo Form::open(array('name'=>'rotate','method'=>'post')); ?>
 <table>
 <tr>
 <th>回転度数</th>
 </tr>
 <tr>
 <td><?php echo Form::input('degrees'); ?></td>
 </tr>
 <tr>
 <td><?php echo Form::submit('submit', ' 回転'); ?></td>
 </table>
 <?php echo Form::close(); ?>

数字を45と入力してみます。時計回りに画像が45度回転しています。

watermark(ファイル名,位置,$padding=5)

画像に透かしイメージを挿入します。第2引数は、透かしの位置をtop、center、middle、bottomで指定します。第3引数は画像の角からのパディングをpixel単位で指定します。

border($size,$color=null)

このメソッドは、画像に境界線を指定します。下記に記述例を表記にしておきます。

app/classes/controller/sample.php

public function action_border(){
 //もしPOST送信されたら
 if(Input::method() == 'POST'){
 $size=Input::post('size');
 $color=Input::post('color');
 Image::load('assets/img/sample/kuranosuke.jpg')
 ->border($size,$color)
 ->output();
 }
 return View::forge('sample/border');
 }

app/views/sample/border.php

<meta charset="utf-8">
<?php echo Form::open(array('name'=>'border','method'=>'post')); ?>
<table>
<tr>
<th>サイズ</th>
<th>カラー</th>
</tr>
<tr>
<td><?php echo Form::input('size'); ?></td>
<td><?php echo Form::input('color'); ?></td>
</tr>
<tr>
<td><?php echo Form::submit('submit', ' ボーダーの挿入'); ?></td>
</table>
<?php echo Form::close(); ?>

サイズを20,カラーを#ffooooと入力してみます。

mask(マスクイメージ)

このメソッドは読み込まれたイメージと指定のマスクイメージのアルファチェンネルをブレンドして画像にマスクを適用します。

rounded(半径,辺の指定,アンチエイリアス)

このメソッドは、画像に角丸を適用します。 半径の指定は必須です。下記に例題を記述しておきます。

app/classes/controller/sample.php

public function action_rounded(){
 //もしPOST送信されたら
 if(Input::method() == 'POST'){
 $radius=Input::post('radius');
 $sides=Input::post('sides');
 $antialias=Input::post('antialias');
 Image::load('assets/img/sample/kuranosuke.jpg')
 //背景色を白に指定
 ->config('bgcolor','#fff')
 ->rounded($radius,$sides,$antialias)
 ->output();
 }
 return View::forge('sample/rounded');
 }

app/views/sample/rounded.php

<meta charset="utf-8">
<?php echo Form::open(array('name'=>'rounded','method'=>'post')); ?>
<table>
<tr>
<th>半径</th>
<th>辺の指定</th>
<th>アンチエイリアス</th>
</tr>
<tr>
<td><?php echo Form::input('radius'); ?></td>
<td><?php echo Form::input('sides'); ?></td>
<td><?php echo Form::input('antialias'); ?></td>
</tr>
<tr>
<td><?php echo Form::submit('submit', ' 角丸画像の作成'); ?></td>
</table>
<?php echo Form::close(); ?>

試しに半径100,辺の指定を『tl tr』と入力してみます。上部の両辺が角丸になっています。

sizes(ファイル名)

このメソッドは、指定の画像のサイズを返します。ファイル名を指定しなければ、現在ロードされている画像のサイズを返します。

grayscale()

このメソッドは、現在の画像をグレースケールに変更します。

save(ファイル名,パーミッション=null)

このメソッドは、画像を保存します。第2引数にパーミッションを指定することが出来ます。

save_pa(先頭付加文字,末尾付加文字=null,拡張子=null,パーミッション=null)

先頭付加文字や末尾付加文字を指定して、以前の画像と同じ場所に保存します。

output(ファイル形式)

このメソッドは、画像を出力して、ヘッダを設定します。

Imageクラスは実際に自分で画像を加工しながらメソッドの使い方を覚えた方が、理解は早いのでなかいかと思いますので、皆さんも簡単なプログラムを作成して加工の方法を試して下さい。

プリセットの使用例

最後に、configファイルにプリセットを作成して、実際に使用してみたいと思います。プリセットを下記のように作成します。

app/config/image.php

'presets'=>array(
 'mypreset'=>array(
 //背景色を白に指定
 'bgcolor'=>"#fff",
 'quality'=>80,
 'actions'=>array(
 array('crop_resize',500,500),
 array('border',20,'#f00'),
 //反時計回りに45度回転
 array('rotate',-45),
 array('rounded',100)
 )
 )
 )

app/classes/controller/sample.php

public function action_preset(){
 Image::load('assets/img/sample/kuranosuke.jpg')
 ->preset('mypreset')
 //->config('bgcolor','#fff')
 ->output();
 return '';
 }

ブラウザで確認してみます。

プリセットでbgcolorを指定してもあまり意味が無いようです。action_presetの4行目のコメントを削除(//を削除)して、bgcolorを白色に指定すると下記のようになりました。

なお、rotate(画像の回転)が有効になっていると、角丸も適用されません。presetのrotate指定を解除すると、下記のように角丸が適用されました。

このようにGDライブラリを使うには不具合を考慮しながら画像を加工しなければならないようです。

本日は以上です。

このエントリーを含むはてなブックマーク Buzzurlにブックマーク livedoorクリップ Yahoo!ブックマークに登録

トラックバック&コメント

この投稿のトラックバックURL:

コメントをどうぞ

このページの先頭へ