# laravel 關於圖片
## 圖片亂樹取名

## 教學
https://www.youtube.com/watch?v=5BD5hAimahQ&ab_channel=Laratips
## media
一開始編輯器先存到media_tmp 然後model_type 等於tmp
然後store的時候replaceMediaByIdMany 然後跑foreach
把真的有的type 改成當前的model type 然後
孤兒資料就會排成去刪除
另外 tmp不用設置這個
只有一對一才要 基本上都會用這個
https://spatie.be/docs/laravel-medialibrary/v9/working-with-media-collections/defining-media-collections#defining-a-fallback-url-or-path
因為relation有singe 這邊會 固定只有一 但如果今天是多筆就不用了
## 原生php
https://doc.houdunren.com/php/9%20%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86.html#%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86
## 如何將文件上傳到 Amazon S3
https://www.youtube.com/watch?v=xZQM9q_QxMA
## 檔案下載
download() 可用於生成一個回應,強制用戶瀏覽器去下載指定路徑的檔案。 download() 將檔案名稱作為其第二個參數,它將作為用戶下載檔案後的新檔名。最後你可以傳遞 HTTP header 陣列作為其第三個參數:
return response()->download($pathToFile);
return response()->download($pathToFile, $name, $headers);
## 檔案回應
file() 用於直接在用戶瀏覽器顯示一個圖片或 PDF 之類的檔案,而不是下載。這個方法接受檔案路徑作為第一個參數,header 陣列作為第二個參數
return response()->file($pathToFile);
return response()->file($pathToFile, $headers);
## 預設大頭照
https://www.youtube.com/watch?v=TqnC96-nXAA
## 檔案路徑 & 副檔名
UploadedFile 類別還包含訪問檔案的全路徑和副檔名的方法。 extension() 會根據檔案內容來猜測檔案的副檔名。該副檔名可能會和客戶端提供的副檔名不同:
$path = $request->photo->path();
$extension = $request->photo->extension();
其他檔案方法
UploadedFile 實例上還有許多可用的方法,可以查看該類別的 API 文件來了解這些方法的詳細信息
## 儲存上傳檔案
要儲存上傳的文件,要先配置好檔案系統。你可以使用 UploadedFile 的 store() 把上傳檔案移動到你的某個磁碟上,該磁碟可能是位在本地檔案系統中的某個位置,甚至像 Amazon S3 這樣的雲儲存空間
store() 接受相對於檔案系統設定的儲存檔案根目錄的路徑。這個路徑不能包含檔案名稱,因為系統會自動生成唯一的 ID 作為檔案名
store() 還接受可選的第二參數,用於儲存檔案的磁碟名稱。這個方法會返回相對於儲存檔案根目錄的文件路徑:
$path = $request->photo->store('images');
$path = $request->photo->store('images', 's3');
假如你不想要被自動升成一個新檔名,你可使用 storeAs() ,這個方法接受路徑. 檔名 以及磁碟名稱來做為參數
$path = $request->photo->storeAs('images', 'filename.jpg');
$path = $request->photo->storeAs('images', 'filename.jpg', 's3');
## 團片 自動傳輸
```
// 自動檔案名產生一個唯一的 ID...
Storage::putFile('photos', new File('/path/to/photo'));
// 手動指定檔案名稱...
Storage::putFileAs('photos', new File('/path/to/photo'), 'photo.jpg');
```
關於 putFile 方法有一些重要的事情需要注意。請注意,我們只有指定目錄名稱,而不是檔案名稱。預設的 putFile 方法會產生一個唯一的 ID 作為檔案名稱。該檔案的路徑會被 putFile 方法所回傳,以便將路徑和剛產生的檔案名稱存入資料庫中。
putFile 和 putFileAs 方法也接受一個用來指定儲存檔案的可見性的參數。如果你是將檔案儲存到像是 S3 的雲端硬碟,並希望檔案能夠被公開存取的話,這個用法會特別好用:
但一個參數傳入也可以

## putFile 不用看 看老師的 寫得非常好
老師影片
https://drive.google.com/drive/folders/19ITMVC3_2ucYHLBckhjWLPzio7JGPQ6w
-- 記得是調用stroage 所以會路徑錯 --
传递给putFile的第一个参数是新文件位置。示例:/path/to/new/file/
第二个参数是File或UploadedFile实例。这可以来自request()->file('uploadedFile')。
因此您的控制器应该读取
```
public function store() {
return Storage::putFile(
storage_path('uploads'),
request()->file('uploadedFile')
);
}
```
https://www.coder.work/article/1356793
https://stackoverflow.com/questions/45419672/laravel-5-4-usage-of-storageputfile
## 另外的圖片上傳
```
這行不錯 產假黨名
$newImageName = time() . '-' . $request->name . '.' .$request->img->extension();
move可放相對 印出來是 存可以 資料庫還沒放過
可嘗試用putfile 在加 storage 去上面參考
$test = $request->img->move('upload/product', $newImageName);
```
## 圖片壓縮 新手道場那本用一樣套件 可過去看詳細(非常建議卡住不懂看新手道場202頁)
- 圖片通常壓縮解析度 dpi 跟尺寸(檔案大小)
http://image.intervention.io/getting_started/installation
安裝好記得去config增加class 用法教學看下面
圖片套件功能及用法
https://iter01.com/460773.html
$a =Image::make()
$a->save( ,80) 第一個參數路徑 第二個品質 80別動
fit會把多的裁掉 但不會變形
- 非常重要的兩個 超級無敵大地雷
- 第一顆地雷
如果你上面用
Storage::putFileAs('photos', new File('/path/to/photo'), 'photo.jpg')
這種會幫你建檔案的
下面這邊會出事 要改
$a->save( ,80) 這邊第一個參數如果放上面putFile的存檔路徑
會錯 原因你存檔的不是一個路徑是一個動作 所以要放在public下面哪個 要自已手寫路徑放在public下面
用public_path 可用public_path().接位置 或 ublic_path(放進來)
https://drive.google.com/drive/folders/19ITMVC3_2ucYHLBckhjWLPzio7JGPQ6w
- 第二顆地雷
當你用上面 用public_path放位置 不會幫你自動建立資料夾
- 最後總結提醒,壓縮的做法跟圖片上傳作法會差很多,不要想著可以先存在壓縮,作法全部改變,做之前先想要哪種
## 進階版

## 參考
model 底層
```
use InteractsWithMedia;
public const HTML_EDITOR = 'tinymce'; //用於tinymce檔案上傳綁定
public const PICTURE_CUTTER = 'croppa'; //用於裁切器非同步上傳綁定新model的暫存綁定
public const API_TEMP = 'api-temp';
protected $guarded = [];
```
上層
```
class MediaTemp extends DolfanMediaTemp
{
const BANNER_COLLECTION_NAME = 'banner';
public function registerMediaConversions(Media $media = null): void
{
$this->addMediaConversion(Banner::SMALL_COLLECTION_NAME)
->width(Banner::SAMLL_SIZE['width'])
->height(Banner::SAMLL_SIZE['height'])
->performOnCollections(self::BANNER_COLLECTION_NAME);
}
}
```
controller
```
<?php
namespace App\Services\Admin\Upload;
use App\Http\Requests\Admin\Upload\UploadToTempRequest;
use App\Models\MediaTemp;
use Dolfan\Models\Constants\FileConstantInterface;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Str;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
use TWJOIN\AdminPanel\Http\Resources\Media\MediaResource;
use TWJOIN\AdminPanel\Traits\HandleMediaTrait;
class UploadService
{
use HandleMediaTrait;
/**
* MediaTemp.
*
* @var MediaTemp
*/
protected $mediaTemp;
public function __construct(MediaTemp $mediaTemp)
{
$this->mediaTemp = $mediaTemp;
}
public function uploadToTemp(UploadToTempRequest $request): ?MediaResource
{
$file = $request->file;
$key = $request->type_name;
$collectionName = data_get($request, 'collection_name');
if (is_null($collectionName)) {
$collectionName = 'default';
}
$temp = $this->mediaTemp->where('key', $key)->first();
$media = $this->uploadMediaByModel($temp, $file, $collectionName);
if (!$media) {
return null;
}
return new MediaResource($media);
}
public function uploadMediaByModel(?HasMedia $model, UploadedFile $file, string $collectionName = 'default', ?string $customFileType = null): Media
{
if (is_null($model)) {
return null;
}
$fileName = Str::random(20);
$extension = $file->getClientOriginalExtension();
$customProperties = [FileConstantInterface::ORIGIN_FILE_NAME => $file->getClientOriginalName()];
if (filled($customFileType)) {
$customProperties[FileConstantInterface::MEDIA_CUSTOM_TYPE] = $customFileType;
$fileName = "{$customFileType}_{$fileName}";
}
return $model
->addMedia($file)
->usingFileName("{$fileName}.{$extension}")
->usingName($fileName)
->withCustomProperties($customProperties)
->toMediaCollection($collectionName);
}
}
```
## laravel-meida-library
https://danielhuang030.pixnet.net/blog/post/268697096
###### tags: `Laravel`