はじめに
Laravelで画像投稿機能を作ったは良いけど、
「投稿される画像が大きかったり小さかったりする..」
「アップロード後に画像が勝手に回転してしまう..」
「画像に埋め込まれた隠し情報が危険って聞いたけど..」
そんな問題を解消していきます。
画像の大きさの問題はCSSで縮尺などを指定すれば表示は小さくできますが、
それだと表示を変えるだけで保存される画像は大きいままです。
これではストレージや通信に負荷がかかってしまいます。
また画像にはEXIF情報
というものが埋め込まれていて、撮影したスマートフォンの情報だったり画像の向き、さらには撮影した場所などが記録されているものもあります。
少し怖いですね。
今回はこれらを同時に最適化する方法をシェアしていきます。
やること
以下の手順で行います。
① 現状のEXIF情報をみてみる
② InterventionImageをインストールする(Composerを使用)
③ InterventionImageを使えるようにする(Configをいじる)
④ Controllerで実際に画像処理を行う
実際にやってみる
① まず現状の画像のEXIF情報をみてみる
これは別にやらなくても良いのですが、
現在画像処理を行っているControllerにおいてdd()メソッドを実行してみます。
dd($image->exif()); // $imageが画像データです
これでブラウザにEXIF情報が表示できます。
ずらっと配列で表示されて、撮影した機種など色々な情報が格納されているのがわかると思います。。
ちなみにdd()は「dump and die」の略なんですね。(知らないで使ってた)
② InterventionImageをインストールする
この余計なEXIFの削除とリサイズ処理と回転(画像の向き)の最適化処理を同時に簡単にできるのがInterventionImage
というものです。
PHPの画像処理ライブラリであるGDとImagickをサポートするパッケージで、
Laravelで画像処理をするならこれ一択、という位置付けのものですね。
GDやImagickを簡単に扱うことができます。
公式はこちら
http://image.intervention.io/getting_started/installation#laravel
以下のコマンドを実行してインストールします。
$php composer.phar require intervention/image
③ InterventionImageを使えるようにする
Config/app.php
に以下の記述を追加します。
追加するのはproviders
とaliases
の2箇所です。
プロバイダとエイリアスの設定ですね。
'providers' => [
Intervention\Image\ImageServiceProvider::class,
],
~中略~
'aliases' => [
'Image' => Intervention\Image\Facades\Image::class,
],
さらにdriver設定の追加を行います。(以下のコマンドを実行)
$php artisan vendor:publish --provider="Intervention\Image\ImageServiceProviderLaravelRecent"
最後に、Configで設定をいじったのでキャッシュをクリアします。(以下のコマンドを実行)
$php artisan config:clear
③ Controllerで実際に処理を行う
ファサードを使う宣言をする
まずは画像処理を行うControllerにおいて以下を記述します。
use Intervention\Image\Facades\Image; // Imageファサードを使う
use Illuminate\Support\Facades\Storage; // Storageファサードを使う
画像処理を行う
InterventionImageでは本当に色々なことができるのですが、
ここでは実際によく使うであろう縦横比を維持したリサイズと、
ファイルをjpg形式に変換する例を示します。
$resized_image = Image::make($posted_image)->fit(640, 360)->encode('jpg');
`$posted_image`が加工前の画像で、`make()`でInterventionImageに加工前の画像を読み込んでいます。 `fit()`は幅と高さを指定しつつ、縦横比が合わない場合はトリミングしてくれるメソッドです。
単純なリサイズならresize()
でも良いのですが、画像がゆがんでしまうのでこのfit()
が便利だと思います。
※InterventionImageでの網羅的な画像処理はこちらのサイトが参考になります。
https://blog.capilano-fw.com/?p=1574#_resize
画像の回転とEXIF情報の処理
最後に本題(?)の画像が勝手に回転する問題とEXIF情報の処理です。
これにはorientate()
を使います。
$resized_image->orientate()->save();
これで自動回転しつつEXIF情報を削除してくれます。
->save()
がないと処理が反映されないので注意です。
ファイル保存する
ファイル保存はstore
メソッドが使えない(GDがサポートしていないというエラーになる)ので
Laravelの機能(ファサード)のStorage::put
を使います。
Storage::put('public/image/' . $image_name, $resized_image);
これで良い感じの大きさになり、画像の向きも正しい向きになり、不要な埋め込み情報も削除された画像が投稿できるようになったはずです! おつかれさまでした〜。