LoginSignup
1
2

More than 1 year has passed since last update.

laravel8 画像をBase64の文字列にエンコード・デコードするアプリを作る

Last updated at Posted at 2021-11-30

目的

  • laravelを用いて画像をBase64の文字列にエンコード・デコードする簡単なアプリを作ってみる

環境

  • ハードウェア環境
項目 情報
OS macOS Big Sur(11.6)
ハードウェア MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)
プロセッサ 2 GHz クアッドコアIntel Core i5
メモリ 32 GB 3733 MHz LPDDR4
グラフィックス Intel Iris Plus Graphics 1536 MB
  • ソフトウェア環境
項目 情報 備考
PHP バージョン 7.4.11 Homebrewを用いてこちらの方法で導入→Mac HomebrewでPHPをインストールする
Laravel バージョン 8.X commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う
MySQLバージョン 8.0.21 for osx10.13 on x86_64 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする

ご注意

  • Base64エンコードはデータ量が多くなるためサイズの大きい画像ファイルには不向きです。サイズの大きい画像ファイルはmultipart/form-data形式でのファイルのやり取りを検討しましょう!

概要

  • Macに直接作成したlaravelのローカル開発環境にて今回のアプリを作成する。
  • 下記機能を持つlaravel8のアプリを作ってみる。
    • 画像 → Base64文字列(エンコード)
    • Base64文字列 → 画像(デコード)
  • 文字列のBase64エンコード・デコードは今回実装しない。
  • 今回のソース

方法

  1. 下記コマンドを実行してlaravel8のアプリを作成する。

    $ composer create-project "laravel/laravel=8.*" laravel8_base64 -vvv
    
  2. 上記コマンドをで作成されたlaravel8_base64ディレクトリに移動して下記コマンドを実行してローカルサーバーを起動する。

    $ php artisan serve
    
  3. 下記にアクセスし、正常にローカルサーバーが起動していることを確認する。

  4. laravel8_base64ディレクトリで下記コマンドを実行してフォームリクエストクラスのファイルを作成する。

    $ php artisan make:request EncodeRequest
    
  5. laravel8_base64/pp/Http/Requests/EncodeRequest.phpを開き下記の様に修正する。

    laravel8_base64/pp/Http/Requests/EncodeRequest.php
    <?php
    
    namespace App\Http\Requests;
    
    use Illuminate\Foundation\Http\FormRequest;
    
    class EncodeRequest extends FormRequest
    {
        /**
         * Determine if the user is authorized to make this request.
         *
         * @return bool
         */
        public function authorize()
        {
            return true;
        }
    
        /**
         * Get the validation rules that apply to the request.
         *
         * @return array
         */
        public function rules()
        {
            return [
                'file' => 'required'
            ];
        }
    }
    
  6. 下記コマンドを実行してフォームリクエストクラスのファイルを作成する。

    $ php artisan make:request DecodeRequest
    
  7. laravel8_base64/pp/Http/Requests/DecodeRequest.phpを開き下記の様に修正する。

    laravel8_base64/pp/Http/Requests/DecodeRequest.php
    <?php
    
    namespace App\Http\Requests;
    
    use Illuminate\Foundation\Http\FormRequest;
    
    class DecodeRequest extends FormRequest
    {
        /**
         * Determine if the user is authorized to make this request.
         *
         * @return bool
         */
        public function authorize()
        {
            return true;
        }
    
        /**
         * Get the validation rules that apply to the request.
         *
         * @return array
         */
        public function rules()
        {
            return [
                'base64_str' => 'required',
            ];
        }
    }
    
  8. ルーティングファイルに下記の内容を記載する。

    laravel8_base64/routes/web.php
    <?php
    
    use App\Http\Controllers\ConvertController;
    use Illuminate\Support\Facades\Route;
    
    /*
    |--------------------------------------------------------------------------
    | Web Routes
    |--------------------------------------------------------------------------
    |
    | Here is where you can register web routes for your application. These
    | routes are loaded by the RouteServiceProvider within a group which
    | contains the "web" middleware group. Now create something great!
    |
    */
    
    Route::get('/', function () {
        return view('welcome');
    });
    
    Route::get('index', [ConvertController::class, 'index'])->name('index');
    Route::post('encode', [ConvertController::class, 'encode'])->name('encode');
    Route::post('decode', [ConvertController::class, 'decode'])->name('decode');
    
  9. 下記コマンドを実行してコントローラークラスのファイルを作成する。

    $ php artisan make:controller ConvertController
    
  10. 作成されたlaravel8_base64/app/Http/Controllers/ConvertController.phpを開き下記の様に記載する。

    laravel8_base64/app/Http/Controllers/ConvertController.php
    <?php
    
    namespace App\Http\Controllers;
    
    use App\Http\Requests\EncodeRequest;
    use App\Http\Requests\DecodeRequest;
    use Illuminate\Support\Facades\Storage;
    use Illuminate\Http\Request;
    
    class ConvertController extends Controller
    {
        public function index()
        {
            return view('index');
        }
    
        public function encode(EncodeRequest $request)
        {
            $postData = $request->validated();
            // ファイルを文字列とする
            $file = file_get_contents($postData['file']);
            // ファイルをbase64でエンコード
            $encodedBase64Str = base64_encode($file);
            // view表示用データの整形
            $viewData = [
                'encodedBase64Str' => $encodedBase64Str,
            ];
    
            return view('index', ['viewData' => $viewData]);
        }
    
        public function decode(DecodeRequest $request)
        {
            $postData = $request->validated();
    
            // base64文字列のData-URL宣言の削除
            $base64Str = str_replace(' ', '+', preg_replace('/^data:image.*base64,/', '', $postData['decodeBase64Str']));
            // ファイルのデコード
            $decodeFile = base64_decode($base64Str);
            // mimeの取得
            $mime = finfo_buffer(finfo_open(FILEINFO_MIME_TYPE), $decodeFile);
    
            // view表示用データの整形
            $viewData = [
                'decodeBase64Str' => $base64Str,
                'mime' => $mime,
            ];
    
            return view('index', ['viewData' => $viewData]);
        }
    }
    
  11. index.blade.phpを作成して下記の内容を記載する。

    laravel8_base64/resources/views/index.blade.php
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Covert</title>
    </head>
    <body>
        <header></header>
        <main>
            <div class="encode">
                <h1>ファイル → Base64 へエンコード</h1>
                @error('file')
                    {{ $message }}
                @enderror
                @if ( empty($viewData['encodedBase64Str']) )
                    <form action="{{ route('encode') }}" method="post" enctype="multipart/form-data">
                        @csrf
                        <input type="file" name="file" id="input-file">
                        <input type="submit" value="変換">
                    </form>
                @else
                    <textarea name="" id="" cols="180" rows="10">{{ $viewData['encodedBase64Str'] }}</textarea>
                @endif
            </div>
            <div class="decode">
                <h1>Base64 → ファイル デコード</h1>
                @error('decodeBase64Str')
                    {{ $message }}
                @enderror
                @if ( empty($viewData['decodeBase64Str']) )
                    <form action="{{ route('decode') }}" method="post">
                        @csrf
                        <input type="text" name="decodeBase64Str" id="input-base64_str">
                        <input type="submit" value="変換">
                    </form>
                @else
                    <img src="data: {{ $viewData['mime'] }};base64, {{ $viewData['decodeBase64Str'] }}">
                @endif
            </div>
            <div class="clear">
                <a href="{{ route('index') }}">
                    <button>内容クリア</button>
                </a>
            </div>
        </main>
        <footer></footer>
    </body>
    </html>
    
  12. 確認

    1. ローカルサーバーを起動して下記にアクセスする。
      1. http://127.0.0.1:8000/decode
    2. 「ファイルを選択」をクリックして何かしらの画像ファイルを選択し「変換」をクリックする。

      Covert.png

    3. Base64文字列が表示されるのですべてコピーする。

      Covert.png

    4. 「Base64 → ファイルデコード」のinput boxにコピーしたBase64文字列を入力して「変換」をクリックする。

      Covert.png

    5. 画像に変換されて表示される。

      Covert.png

参考文献

1
2
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
1
2