初心者のプログラミング日記

プログラミング初心者の日記

プログラミングに関することを書いていきます。

Laravelで画像のアップロードからリサイズして表示まで

まず、Reactを書いていきます。

class Example extends React.Component{
    constructor(props){
        super(props);
        this.state={img:"",image:""}


        this.uploadFile = this.uploadFile.bind(this);
        this.onSubmit = this.onSubmit.bind(this);
    }

    uploadFile(e){
        this.setState({ img: e.target.files[0]})
    }

    onSubmit(e){
        e.preventDefault()
        const data = new FormData();
        data.append('img', this.state.img ? this.state.img : '');
        axios
             .post('api/uploadFile', data)
             .then(res => {this.setState({image:res.data});})
             .catch(error=>{console.log(error)})
    }

    render(){
        return(
            <div>
              <form onSubmit={this.onSubmit}>
                  <input type="file" onChange={this.uploadFile} />
                  <button type="submit">保存</button>
              </form>
              
               //APIで返ってきたパスがセットされる
              <img src={this.state.image} />
            </div>
        );
    }
}

uploadFileでファイル情報をimgにセットしています。
onSubmitではファイルデータを送信するためにFormDataオブジェクトを使っています。
appendメソッドでキーと値を追加しています。



次にルーティングの設定です。

Route::group(['middleware' => 'api'], function(){
    Route::post('uploadFile','FileController@uploadFile');
});

コントローラを書く前に準備をします。
まず、以下のコマンドを打ってください。

composer require intervention/image

そしたら以下のファイルに追記します

<--場所はconfig/app.php -->

'providers' => [
<--省略-->
Intervention\Image\ImageServiceProvider::class, <-- 追加-->
 ],

'aliases' => [
<--省略-->
'InterventionImage' => Intervention\Image\Facades\Image::class,<-- 追加-->
 ],

準備が整ったのでコントローラを書いていきます。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator; //追加
use Intervention\Image\Facades\Image; //追加

class FileController extends Controller
{
    public function uploadFile(Request $request){

        $validator=Validator::make($request->all(),[
            'img'=>'nullable|file|image|mimes:jpeg,png,jpg,gif|max:2048' //バリデーターの生成
        ]);

        if ($validator->fails()){//エラーがある場合
            return response()->json($validator->errors(), 400);
        }

        if ($img = $request->file('img')){
            //Image::make()で画像読込
            //file_get_contents — ファイルの内容を全て文字列に読み込む
            //getRealPath():アップロードしたファイルのパスを取得
            $image = Image::make(file_get_contents($img->getRealPath()));

            //縦横比を維持したままリサイズ
            $image->resize(300, null, function ($constraint) {
                $constraint->aspectRatio();
            });

            ////getClientOriginalName():アップロードしたファイルのオリジナル名を取得
            $fileName=$img->getClientOriginalName();
            $image->save(public_path().'/images/'.$fileName); //public/imagesに保存

            $path='/images/'.$fileName; //パスを取得
           
            return $path;

        }
    }
}

バリデーターの生成とバリデーションルールに関しては以下のURLを参考に
https://readouble.com/laravel/7.x/ja/validation.html

画像はpublic/imagesに保存されます。
これで保存した画像のパスを返し、React側で表示しています。

参考にしたサイト
https://soybelln.com/blog/upload-image-react-and-laravel/