画像を投稿するWEBアプリを作ってみました。
タイトル:俺が飲んだもの
https://oreno-drink.com/
俺が飲んだものを俺がアップする自分の記録用に作ったアプリです。
なぜ作ったか?なんとなく楽しそうだし自分が飲んだ珍しいものを記録したいじゃないですか。日々いろんな飲み物を飲むわけだし。
サーバーはさくらインターネットのレンタルサーバを使っています。画像を保存することは問題なくできるのですが、画像のファイルが大きく画像の読み込みに時間がかかることに悩んでいました。
画像ありきなアプリだけに画像の読み込みが遅いのは致命的。イライラします。
PageSpeed Insightsで調べるとカメラで撮った画像は一枚当たり2,500 ~ 3,500KiBありかなり重い状態。
なんとか画像を圧縮できる方法はないかと調べ、一度試したのが画像を一度LINEで送信してから保存して再度サイトにアップするというやり方です。これだと確かに画像サイズ100 ~ 180KiBと小さくなり、読み込みも早くなるのですが、、、なんといっても手間だし自分以外の人がアップロードした画像は小さくできません。
何かいい方法はないのか、、調べてみるとIntervention Imageというライブラリが良さそう。試そう。
Intervention Image公式ページ
http://image.intervention.io/
詳しい使い方はこちらの方が紹介してくれてます。
https://blog.capilano-fw.com/?p=1574
が、いくつかのサイトで保存方法を調べても画像単体でだけの説明しかされておらず、文字や説明までも含んだ保存方法の説明は見つけられませんでした。
↓ 通常の保存方法。保存はされるが、画像サイズが大きすぎる。
if($request->hasFile('image')){
$filenameWithExt = $request->file('image')->getClientOriginalName();
$filename = pathinfo($filenameWithExt ,PATHINFO_FILENAME);
$extension = $request->file('image')->getClientOriginalExtension();
$fileNameToStore = $filename . '_'. time(). '.'.$extension;
$path = $request->file('image')->storeAs('public/image', $fileNameToStore);
} else {
$fileNameToStore = null;
}
$request->user()->drinks()->create([
'name' => $request->name,
'body' => $request->body,
'score' => $request->score,
'place' => $request->place,
'image' => $fileNameToStore,
]);
Intervention Imageを使って画像サイズを指定。
//追加
use Intervention\Image\ImageManagerStatic as InterventionImage;
if($request->hasFile('image')){
$filenameWithExt = $request->file('image')->getClientOriginalName();
$filename = pathinfo($filenameWithExt ,PATHINFO_FILENAME);
$extension = $request->file('image')->getClientOriginalExtension();
$fileNameToStore = $filename . '_'. time(). '.'.$extension;
$path = $request->file('image')->storeAs('public/image', $fileNameToStore);
//追加
$image = InterventionImage::make(public_path("storage/image/{$fileNameToStore}"))->fit(1200, 1200);
$image->save();
} else {
$fileNameToStore = null;
}
$request->user()->drinks()->create([
'name' => $request->name,
'body' => $request->body,
'score' => $request->score,
'place' => $request->place,
'image' => $fileNameToStore,
]);
Copmoserでインストールしたりconfig/app.phpをいじったりはしましたが追加したのは基本的に↓のコードだけ。
$image = InterventionImage::make(public_path("storage/image/{$fileNameToStore}"))->fit(1200, 1200);
$image->save();
これだけで、同じ画像、同じアップロード方法で3,500.5 KiB → 200.1 KiB とファイルサイズを小さくできました。読み込みも早くなり解決。