iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

2

商品圖片處理

圖片上傳

當使用者有上傳圖片時,則必須將檔案儲存到主機目錄中,才能供使用者做圖片存取,圖片存取的程式邏輯會像下面範例這樣

app/Http/Controllers/MerchandiseController.php

<?PHP
namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Shop\Entity\Merchandise;
use Illuminate\Support\Facades\Log;
use Validator; //驗證器
use Image;

class MerchandiseController extends Controller
{
    //商品資料更新處理
    public function merchandiseItemUpdateProcess($merchandise_id)
    {
        //撈取商品資料
        $Merchandise = Merchandise::findOrFail($merchandise_id);
        //接收輸入資料
        $input = request()->all();

        //...以下省略...

        if(isset($input['photo']))
        {
            //有上傳圖片
            $photo = $input['photo'];
            //檔案副檔名
            $file_extension = $photo->getClientOriginalExtension();
            //產生自訂隨機檔案名稱
            $file_name = uniqid().'.'.$file_extension;
            //檔案相對路徑
            $file_relative_path = 'images\\merchandise\\'.$file_name;
            //檔案存取目錄為對外公開public目錄下的相對位置
            $file_path = public_path($file_relative_path);

            Log::notice('原圖片路徑 = '.$photo);
            Log::notice('圖片類型 = '.$photo->getMimeType());
            Log::notice('新圖片路徑 = '.$file_path);
            //裁切圖片
            $image = Image::make($photo)->fit(450, 300)->save($file_path);
            //設定圖片檔案相對位置
            $input['photo'] = $file_relative_path;
        }

        $Merchandise->update($input);

        //重新導向到商品編輯頁
        return redirect('/merchandise/'.$Merchandise->id.'/edit');
    }
}
?>

Laravel會將所有請求中的檔案格式的資料,轉換成Illuminate\Http\UploadedFile物件,所以可以使用這個物件的getClientOriginalExtension()方法取得檔案的副檔名,並產生隨機的字串重新命名檔案名稱,而所有檔案都放在images/merchandise/的相對路徑的目錄下。

//有上傳圖片
$photo = $input['photo'];
//檔案副檔名
$file_extension = $photo->getClientOriginalExtension();
//產生自訂隨機檔案名稱
$file_name = uniqid().'.'.$file_extension;
//檔案相對路徑
$file_relative_path = 'images/merchandise/'.$file_name;

圖片長寬比例問題

為了排版的美觀,會限制圖片的長寬比例是多少,但是我們無法強迫使用者一定要會美工軟體,把圖片都手動裁切才進行上傳,這時候就需要透過程式幫忙做裁切的動作,而使用Laravel的好處在這裡就可以看出來了,因為圖片處理這個需求,幾乎是每個專案都必備的功能,當有這樣的跨專案需求時,將這個圖片處理的程式套件化,不僅可以幫自己在跨專案開發時,能夠快速的安裝共用套件,公開的程式碼也可以讓其他Laravel社群的人,也可以一起共用套件,一起對套件進行維護及除錯。

當遇到跨專案的需求時,可以先到Packagist搜尋Laravel image看看有沒有已經現成可以用得套件,如果沒有再自己開發套件分享到Laravel社群,讓社群能夠持續地注入養分成長茁壯,而在搜尋套件時,有看到intervention/image的Laravel圖片套件,所以我們直接使用Composer安裝此套件,就可以方便的使用套件處理圖片了

composer require intervention/image
https://ithelp.ithome.com.tw/upload/images/20191015/2010569464Djbl4Gks.png

在安裝完成後,依照intervention/image提供的Laravel安裝步驟,可以在config/app.php檔案中設定圖片套件,當設定完成後,直接在Laravel類別上方使用use Image;就可以使用此套件了

config/app.php

<?php

return [
    //自動載入Service Providers
    'providers' => [
        //圖片相關
        Intervention\Image\ImageServiceProvider::class,
    ],

    //類別命名
    'aliases' => [
        //圖片相關
        'Image' => Intervention\Image\Facades\Image::class,
    ],
];

裁切圖片

在設定完圖片檔案相對位置後,將檔案存在public目錄中,讓使用者可以直接輸入網址存取該檔案,此時可以用Laravel提供的public_path()輔助方法,產生該檔案的實體路徑是在哪,產生出來的路徑在Homestead環境中會像是E:\Web\LaravelTest\public\images\merchandise\59b249ddf2ea7.jpg,所以當圖片處理完成後,會需要將圖片存到此路徑下

//檔案相對路徑
$file_relative_path = 'images\\merchandise\\'.$file_name;
//檔案存取目錄為對外公開public目錄下的相對位置
$file_path = public_path($file_relative_path);
//裁切圖片
$image = Image::make($photo)->fit(450, 300)->save($file_path);
//設定圖片檔案相對位置
$input['photo'] = $file_relative_path;

使用Image::make($photo)就可以直接將圖片資料物件化,然後透過->fit()函數限制片要裁切的長度,最後使用->save()儲存檔案到指定路徑下即可,最後將圖片的相對路徑設定為要更新到商品資料表的資料。

當設定完需要更新的資料後,在原本的商品物件中,可以直接用 $Merchandise->update(); 方法對商品資料進行更新,並在更新完成後重新導向到商品編輯頁,這樣就可以馬上看到商品資料更新的結果了。

$Merchandise->update($input);
//重新導向到商品編輯頁
return redirect('/merchandise/'.$Merchandise->id.'/edit');

上一篇
[Day 38] Laravel實作 - 商品管理與瀏覽(五)
下一篇
[Day 40] Laravel實作 - 商品管理與瀏覽(七)
系列文
Laravel從入門到放棄…………原生PHP (疑?48

尚未有邦友留言

立即登入留言