65
70

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

LaravelでIntervention Imageを使って加工した画像をS3へ保存する

Last updated at Posted at 2018-11-02

はじめに

PHPで画像の加工を行う場合いろいろな方法がありますが、フレームワークにLaravelを利用している場合は「Intervention Image」がオススメです。

導入が簡単でリサイズやクロップの記述も簡単といいことずくめなのですが、
加工した画像をS3へアップロードする際に少し躓いたので備忘録として記します。

なお、Laravelのバージョンは5.7にて確認しています。

Intervention Image

http://image.intervention.io/getting_started/introduction
画像処理のライブラリであるGDと共にIntervention Imageをサーバへインストールします。

# yum install php-gd
# systemctl reload httpd.service
# php composer.phar require intervention/image

Laravelの設定ファイルの$providers配列にIntervention Imageのサービスプロバイダを追加します。

config/app.php
'providers' => [
    Intervention\Image\ImageServiceProvider::class,
],

同じく設定ファイルの$aliases配列にファサードを追加します。

config/app.php
'aliases' => [
    'Image' => Intervention\Image\Facades\Image::class,
],

キャッシュをクリアして準備は完了です。

# php artisan config:clear

putメソッドを利用した画像アップロード

putメソッドを利用した場合は下記の様にシンプルに記述できます。
生成されたIntervention Imageのインスタンスをstringへキャストするのがポイントでしょうか。

詳しくはlaracastsの下記のフォーラムで質疑されていました。
https://laracasts.com/discuss/channels/laravel/image-intervention-with-laravel-53?page=1

app/Http/Controllers/SampleController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Intervention\Image\Facades\Image;

class SampleController extends Controller
{
     /**
     * Handle a image upload request for the application.
     *
     * @param  $request
     * @return \Illuminate\Http\Response
     */
    public function upload(Request $request)
    {
        // バリデーション
        Validator::make($request->all(), [
            'image' => 'file|image|max:1024|nullable'
        ])->validate();

        if ($request['image']) {
            $file = $request->file('image');
            $name = $file->getClientOriginalName();

            // 画像を横幅300px・縦幅アスペクト比維持の自動サイズへリサイズ
            $image = Image::make($file)
                ->resize(300, null, function ($constraint) {
                    $constraint->aspectRatio();
                });

            // configファイルに定義したS3のパスへ画像をアップロード
            Storage::put(config('filesystems.s3.url').$name, (string) $image->encode());
        }

        return redirect()->route('index');
    }
}

putFileAsメソッドを利用した画像アップロード

putメソッドを利用できれば簡単でしたが、実際にはS3へアップする際にファイル名を指定したい場合もあるでしょう。
その場合はputFileAsメソッドを利用するのですが、putメソッドのようにシンプルな記述でできずに悩みました。調べてもあまり情報が見つからない。

結局、リサイズした画像をいったんローカルへ保存してからS3へアップロードし、その後ローカルの画像を削除する、といった流れで行いました。

app/Http/Controllers/SampleController.php
<?php

namespace App\Http\Controllers;

use Carbon\Carbon;
use Illuminate\Http\File;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Intervention\Image\Facades\Image;

class SampleController extends Controller
{
     /**
     * Handle a image upload request for the application.
     *
     * @param  $request
     * @return \Illuminate\Http\Response
     */
    public function upload(Request $request)
    {
        // バリデーション
        Validator::make($request->all(), [
            'image' => 'file|image|max:1024|nullable'
        ])->validate();

        if ($request['image']) {
            $now = date_format(Carbon::now(), 'YmdHis');
            $file = $request->file('image');
            $name = $file->getClientOriginalName();

            // 画像を横幅300px・縦幅アスペクト比維持の自動サイズへリサイズして一時ファイル保存先へ格納
            $tmpFile = $now . '_' . $name;
            $tmpPath = storage_path('app/tmp/') . $tmpFile;
            $image = Image::make($file)
                ->resize(300, null, function ($constraint) {
                    $constraint->aspectRatio();
                })
                ->save($tmpPath);

            // configファイルに定義したS3のパスへ指定したファイル名で画像をアップロード
            Storage::putFileAs(config('filesystems.s3.url'), new File($tmpPath), $file, 'public');

            // 一時ファイルを削除
            Storage::disk('local')->delete('tmp/' . $tmpFile);
        }

        return redirect()->route('index');
    }
}

おわりに

putメソッドがシンプルな記述だったので、putFileAsメソッドでも同様にできると油断したため、予想以上にはまってしまいました。

65
70
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
65
70

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?