Laravel アップロードされた画像のサイズを変換して保存する

intervention imageというライブラリを使う。

これにより、必要以上のクソデカ画像をアップロードされることなどを阻止できる。
ユーザーアイコンなど最低限のサイズでいいファイルなどに適用する。

今回はdockerを前提に解説。

インストール

まずはコンテナ内のプロジェクトディレクトリに移動する。

composer require intervention/image

を実行。

パスを通す

もしまだファイルアップロード用にパスを通していなければ、

同じくコンテナ内のプロジェクトディレクトリで、

php artisan storage:link

を実行。

画像をアップロードしたければ無条件にこの処理が必要になる。

config/app.phpを編集

次にファイルを編集する。

'providers' => [ ]内の末尾に下記を追加。

// Add Intervention Image.
  Intervention\Image\ImageServiceProvider::class,

'aliases' => []内の「'Hash' => Illuminate\Support\Facades\Hash::class,」

// Add Intervention Image.
'Image' => Intervention\Image\Facades\Image::class,

※もしこの時点で「'Intervention\Image\ImageServiceProvider' not found」になるなら、「composer require intervention/image」が完了していない。
正しくない場所でコマンドを実行している可能性がある(ladockならlaradockディレクトリ上で行ってしまったとか)

コントローラー

画像の処理行いたいコントローラーの冒頭に

use Image;

を追記。

画像を処理する関数も合わせた書くと、こんな感じになる。

//Hogecontroller.php
use Image; //冒頭に追記

public function update(Request $request){
        Image::make($request->file('files')[0])->resize(300, 300, function ($constraint) {
            $constraint->aspectRatio();
        })->save(storage_path(('app/public/img/hoge.jpg'), 100));
}

縦横の最大サイズを300に合わせにいっているようなイメージ。

後は、フロント側から子のコントローラー内のメソッド(今回でいうupdate)を呼び出してあげればいい。

フロント側

一応解説するけどあくまで参考程度に。

今回はvueを使う。

別にbladeでもreactでもいい。

//Hoge.vue
<template>
    <div>
            <input type="file" class="form-control-file " ref="file" @change="fileSelected"
             accept=".jpg,.jpeg,.png,.gif" >
    </div>
</template>

<script>
export default {
        data: () => ({
            fileinfo: null,
        }),
        methods: {
            fileSelected(event) {
                this.fileInfo = event.target.files[0] //選択されたファイルの情報を変数に格納
            },
            submit() {
                let postData = new FormData()
                postData.append('file[0]', this.fileInfo)
                axios.post("/api/update", postData)
            }
        },
    }
</script>

なんかfile[0]って名前のオブジェクトで渡さないとあかんみたい。

コントローラー側で受け取るときは、$request->file('files')[0]って表現になる。

//api.php
Route::post('/update', [HogeController::class, 'update']);

GDをインストール

GDとかいうライブラリがないと、動かないらしい。

このままが画像処理のメソッドを走らせると

GD Library extension not available with this PHP installation.とのエラーが出た。

Dockerfileの編集

Dockerfileを編集

編集前

FROM php:8.0-fpm-buster
SHELL ["/bin/bash", "-oeux", "pipefail", "-c"]

ENV COMPOSER_ALLOW_SUPERUSER=1 \
    COMPOSER_HOME=/composer

COPY --from=composer:2.0 /usr/bin/composer /usr/bin/composer

RUN apt-get update && \
    apt-get -y install git unzip libzip-dev libicu-dev libonig-dev && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* && \
    docker-php-ext-install intl pdo_mysql zip bcmath

COPY ./php.ini /usr/local/etc/php/php.ini

WORKDIR /work

編集後

FROM php:8.0-fpm-buster
SHELL ["/bin/bash", "-oeux", "pipefail", "-c"]

ENV COMPOSER_ALLOW_SUPERUSER=1 \
    COMPOSER_HOME=/composer

COPY --from=composer:2.0 /usr/bin/composer /usr/bin/composer

RUN apt-get update && \
    apt-get -y install git unzip libzip-dev libicu-dev libonig-dev libfreetype6-dev libjpeg62-turbo-dev libpng-dev && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* && \
    docker-php-ext-configure gd --with-freetype --with-jpeg && \
    docker-php-ext-install -j$(nproc) gd && \
    docker-php-ext-install intl pdo_mysql zip bcmath

COPY ./php.ini /usr/local/etc/php/php.ini

WORKDIR /work

何が変わったかというと、

RUNの2行目を変更

apt-get -y install git unzip libzip-dev libicu-dev libonig-dev && \

apt-get -y install git unzip libzip-dev libicu-dev libonig-dev libfreetype6-dev libjpeg62-turbo-dev libpng-dev && \

RUN内に下記を追記

docker-php-ext-configure gd --with-freetype --with-jpeg && \ docker-php-ext-install -j$(nproc) gd && \

リビルド&再起動

今度はコンテナの外でコマンドを実行する。

プロジェクトディレクトリに移動して、

docker compose build --no-cache

docker compose stop

docker compose up -d

これらを実行。

laradockならdocker composeではなく

docker-composeになるかも。

stopとupをしてあげないと反映されなかった。

これで、プロジェクトディレクトリ\storage\app\public\img\hoge.jpg

内に、縦横サイズ上限300pxに変換された画像が保存される。

参考にしたサイト

Docker上でPHP拡張モジュール『GD』を有効化する

無制限に質問可能なプログラミングスクール!

万が一転職できない場合は、転職保障全額返金できるコースもあり!!

無制限のメンター質問対応

 

DMMウェブキャンプでプログラミングを学習しませんか?

独学より成長スピードをブーストさせましょう!

 

まずは無料相談から!

おすすめの記事