Laravelで画像処理(アップロード/リサイズ/サムネイル)を行なう方法
LaravelでLaravelで画像処理(アップロード/リサイズ/サムネイル)を行なう方法をまとめました。
Laravel学習をしている方の参考になれば幸いです。
ソースはgithubで公開しています。
manabubannai/Laravel_Image_Manipulation
Laravelで画像処理をするパッケージのインストール
intervention/image というパッケージを利用します。
intervention/image – Packagist
以下のコマンドでインストールします。
$ composer require intervention/image
つづいて、intervention/imageのセットアップを行ないます。
編集ファイル:app/config/app.php
// 124行目に以下を追加
'InterventionImageImageServiceProvider',
// 192行目に以下を追加
'Image' => 'InterventionImageFacadesImage',
以上でセットアップが完了です。かんたんですね( ◜◡‾)
Laravelで画像処理をするさまざまな方法
まずは、Web上から画像をもってきて表示してみます。
以下の画像を利用してみます。
テスト用画像
以下のプログラムを実行すると画像が取得されていることがわかります。
Route::get('/', function(){
$image = Image::make(file_get_contents('http://goo.gl/uDTEzv'));
return $image->response('jpg');
});
つぎに画像をリサイズしてみます。
以下のプログラムを実行してみてください。
Route::get('/', function(){
$image = Image::make(file_get_contents('http://goo.gl/uDTEzv'));
$image->resize(100,100);
return $image->response('jpg');
});
幅だけを設定して、高さは自動処理にしたい場合は以下のように記述します。
$image->resize(100, null, function ($constraint) {
$constraint->aspectRatio();
});
クロップしたい場合は以下のように記述します。
$image->crop(100, 100);
デフォルトでは中心部からクロップされますが、クロップ位置を調整した場合は以下のように記述します。
// 左上からクロップする
$image->crop(100, 100, 0, 0);
白黒にした場合は以下のように記述します。
こりゃ便利ですね。
$image->greyscale();
もちろんチェーンメソッドも使えます。
以下が例となります。
$image->crop(200, 200)->greyscale();
その他のコマンドは公式マニュアルからご覧ください。
» Intervention Image – Introduction
Laravelを使って画像をフォルダに保存する方法
まず、publicフォルダ内にimagesフォルダを作っておきます。
その後、以下のように記述します。
Route::get('/', function(){
$image = Image::make(file_get_contents('http://goo.gl/uDTEzv'));
$image->crop(200, 200)->greyscale()->save(public_path(). '/images/sample.jpg');
return $image->response('jpg');
});
ここですこしリファクタリングします。
Route::get('/', function(){
$image = Image::make(file_get_contents('http://goo.gl/uDTEzv'));
$file = 'sample.jpg';
$path = public_path() . '/images/';
$image->save($path . $file) // 画像を保存する
->crop(200, 200) // 画像をクロップする
->greyscale() // 画像を白黒にする
->save($path . 'thumbnail-' . $file); // 加工した画像を保存する
return $image->response('jpg');
});
Laravelを使ってフォームから画像をアップロードする方法
まずは、ルートに以下を記述します。
Route::resource('photos', 'PhotosController');
次に以下のコマンドを実行
$ php artisan controller:make PhotosController
するとPhotosControllerが出来上がるので以下を記述します。
編集ファイル:app/controllers/PhotosController.php
public function create(){
return View::make('photos.create');
}
つぎにビューを作成します。
新規作成ファイル:app/views/photos.create.blade.php
Laravelで画像処理します
{{ Form::open(['route' => 'photos.store', 'files' => true]) }}
{{ Form::hidden('user_id', Auth::user()->id) }}
{{ Form::label('fileName', 'アップロード') }}
{{ Form::file('fileName') }}
{{ Form::submit('アップロードする') }}
{{ Form::close() }}
つぎにPhotosControllerに以下を追記します。
編集ファイル:app/controllers/PhotosController.php
public function store(){
// リクエストの全入力を取得する
$input = Input::all();
dd(Input::file('fileName'));
}
このままでは、Auth部分でエラーが発生するので、DBの作成を行います。
usersテーブルを作って、Laravelとコネクトしておいてください。
以下の写真のような簡易なものでOKです。
それでは、テストを行なってみましょう。
localhost:8000/photos/createにアクセスし、画像をアップロードします。
すると以下の結果が表示されます。
object(SymfonyComponentHttpFoundationFileUploadedFile)#9 (7) {
["test":"SymfonyComponentHttpFoundationFileUploadedFile":private]=>
bool(false)
["originalName":"SymfonyComponentHttpFoundationFileUploadedFile":private]=>
string(8) "jq01.png"
["mimeType":"SymfonyComponentHttpFoundationFileUploadedFile":private]=>
string(9) "image/png"
["size":"SymfonyComponentHttpFoundationFileUploadedFile":private]=>
int(46368)
["error":"SymfonyComponentHttpFoundationFileUploadedFile":private]=>
int(0)
["pathName":"SplFileInfo":private]=>
string(36) "/Applications/MAMP/tmp/php/php33b0p7"
["fileName":"SplFileInfo":private]=>
string(9) "php33b0p7"
}
正常に動いていることが確認できたら、次にすすみましょう。
PhotosControllerコントローラーを作成していきます。
編集ファイル:app/controllers/PhotosController.php
public function store(){
// リクエストの全入力を取得する
$input = Input::all();
// getClientOriginalName():アップロードしたファイルのオリジナル名を取得します
$fileName = $input['fileName']->getClientOriginalName();
// getRealPath():アップロードしたファイルのパスを取得します。
$image = Image::make($input['fileName']->getRealPath());
// 画像を保存する
$image->save(public_path() . '/images/' . Auth::user()->name . '/' . $fileName);
}
Auth::user()->name
に注目してください。
現在は認証システムを構築していないのでこのままではエラーが起きます。
それをさけるために、routes.phpに以下を追記します。
Auth::loginUsingID(1);
これで、超簡易版の認証システムが完成しました。
それでは、プログラムを実行してみましょう。
しかし、エラーが起きることがわかります。
原因としては、Auth::user()->name
のフォルダを作っていなかったためです。
以下のように解決できます。
public function store(){
// リクエストの全入力を取得する
$input = Input::all();
// getClientOriginalName():アップロードしたファイルのオリジナル名を取得します
$fileName = $input['fileName']->getClientOriginalName();
// getRealPath():アップロードしたファイルのパスを取得します。
$image = Image::make($input['fileName']->getRealPath());
// Auth::user()->nameのフォルダがあるかどうかを確認し、ない場合は新規作成する
File::exists(public_path() . '/images/' . Auth::user()->name) or File::makeDirectory(public_path() . '/images/' . Auth::user()->name);
// 画像をサーバーに保存する
$image->save(public_path() . '/images/' . Auth::user()->name . '/' . $fileName);
}
これでほぼ完成ですが、最後にサムネイルの保存をしてみます。
$image->save(public_path() . '/images/' . Auth::user()->name . '/' . $fileName)
->resize(200, null, function ($constraint) {$constraint->aspectRatio();})
->greyscale()
->save(public_path() . '/images/' . Auth::user()->name . '/200-' . $fileName);
以上でサムネイルの保存ができました。
参考になれば幸いです( ◜◡‾)
番外編:画像のPathをDBに保存するコード
// こんな感じでOK
$post->image = 'images/'. $fileName;
※コード:manabubannai/Laravel_Image_Manipulation
※参考記事Image Manipulation
※P.S:無料メルマガで発信中:過去の僕は「ブログ発信で5億円」を稼ぎました。次は「30億円」を目指します。挑戦しつつ、裏側の思考を「メルマガ」から発信します。不満足なら1秒で解約できます。無料登録は「こちら」です。