lidai / laravel-imageup
使用 Intervention image 为 Laravel eloquent 模型自动上传、调整大小和裁剪图片
Requires
- php: ^7.3|^8.0
- intervention/image: ^2.4|^3.4
- laravel/framework: ~5.4.0|~5.5.0|~5.6.0|~5.7.0|~5.8.0|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0
Requires (Dev)
- dms/phpunit-arraysubset-asserts: ^0.2.0|^0.3|^0.4|^0.5
- orchestra/testbench: ^4.0|^5.0|^7.0|^8.0|^9.0
- phpunit/phpunit: ^8.0|^9.0|^10.0|^11.0
README
lidai/laravel-imageup 是一个特性,它为您提供了自动上传、调整大小和裁剪图片的功能,同时拥有大量的自定义选项。
安装
您可以通过 composer 安装此包
$ composer require lidai/laravel-imageup
该包将自动注册自己。如果您需要手动注册,可以在 config/app.php 提供者数组中添加它
Lidai\ImageUp\ImageUpServiceProvider::class
您可以选择使用以下命令发布配置文件:
php artisan vendor:publish --provider="Lidai\ImageUp\ImageUpServiceProvider" --tag="config"
这将创建包含所有设置的 config/imageup.php
入门
要使用此特性,您只需在 Eloquent 模型中添加 use HasImageUploads 并定义所有需要存储在数据库中的图像字段。
模型
<?php namespace App; use Lidai\ImageUp\HasImageUploads; use Illuminate\Database\Eloquent\Model; class User extends Model { use HasImageUploads; // assuming `users` table has 'cover', 'avatar' columns // mark all the columns as image fields protected static $imageFields = [ 'cover', 'avatar' ]; }
一旦在模型中标记了所有图像字段,它将在保存模型时自动上传图像,通过挂钩 Model::saved() 事件。它还会将新的存储文件路径更新到数据库中,如果找到旧图像,则在新图像上传后将其删除。
图像字段在数据库表中应为
VARCHAR类型,以存储上传图像的路径。
在控制器中
<?php namespace App; use App\Http\Controllers\Controller; class UserController extends Controller { public function store(Request $request){ return User::create($request->all()); } }
请确保运行
php artisan storage:link以从公共存储磁盘查看图像
就是这样,在上述设置下,当您通过 POST 请求调用 store 方法时,如果请求中存在名为 cover 或 avatar 的文件,它将自动上传。
上传字段选项
ImageUp 允许您对上传和调整大小的处理进行大量自定义,以下是可以自定义的内容:
<?php namespace App; use Lidai\ImageUp\HasImageUploads; use Illuminate\Database\Eloquent\Model; class User extends Model { use HasImageUploads; // which disk to use for upload, can be override by field options protected $imagesUploadDisk = 'local'; // path in disk to use for upload, can be override by field options protected $imagesUploadPath = 'uploads'; // auto upload allowed protected $autoUploadImages = true; // all the images fields for model protected static $imageFields = [ 'avatar' => [ // width to resize image after upload 'width' => 200, // height to resize image after upload 'height' => 100, // set true to crop image with the given width/height and you can also pass arr [x,y] coordinate for crop. 'crop' => true, // what disk you want to upload, default config('imageup.upload_disk') 'disk' => 'public', // a folder path on the above disk, default config('imageup.upload_directory') 'path' => 'avatars', // placeholder image if image field is empty 'placeholder' => '/images/avatar-placeholder.svg', // validation rules when uploading image 'rules' => 'image|max:2000', // override global auto upload setting coming from config('imageup.auto_upload_images') 'auto_upload' => false, // if request file is don't have same name, default will be the field name 'file_input' => 'photo', // if field (here "avatar") don't exist in database or you wan't this field in database 'update_database' => false, // a hook that is triggered before the image is saved 'before_save' => BlurFilter::class, // a hook that is triggered after the image is saved 'after_save' => CreateWatermarkImage::class ], 'cover' => [ //... ] ]; // any other than image file type for upload protected static $fileFields = [ 'resume' => [ // what disk you want to upload, default config('imageup.upload_disk') 'disk' => 'public', // a folder path on the above disk, default config('imageup.upload_directory') 'path' => 'docs', // validation rules when uploading file 'rules' => 'mimes:doc,pdf,docx|max:1000', // override global auto upload setting coming from config('imageup.auto_upload_images') 'auto_upload' => false, // if request file is don't have same name, default will be the field name 'file_input' => 'cv', // a hook that is triggered before the file is saved 'before_save' => HookForBeforeSave::class, // a hook that is triggered after the file is saved 'after_save' => HookForAfterSave::class ], 'cover_letter' => [ //... ] ]; }
自定义文件名
在某些情况下,您可能需要自定义保存的文件名。默认情况下,它将是 $file->hashName() 生成的哈希。
您可以通过在模型上添加一个名为 {fieldName}UploadFilePath 的方法来实现
class User extends Model { use HasImageUploads; // assuming `users` table has 'cover', 'avatar' columns // mark all the columns as image fields protected static $imageFields = [ 'cover', 'avatar' ]; // override cover file name protected function coverUploadFilePath($file) { return $this->id . '-cover-image.jpg'; } }
上述方法将始终保存上传的封面图像为 uploads/1-cover-image.jpg。
请确保从覆盖方法中返回仅相对路径。
请求文件将作为 $file 参数传递给此方法,因此您可以根据需要获取扩展名或原始文件名等来构建文件名。
// override cover file name protected function coverUploadFilePath($file) { return $this->id .'-'. $file->getClientOriginalName(); } /** Some of methods on file */ // $file->getClientOriginalExtension() // $file->getRealPath() // $file->getSize() // $file->getMimeType()
可用方法
您不仅限于使用自动上传图像功能。此特性还提供了以下方法,您可以使用它们手动上传和调整图像大小:
注意:请确保在模型中或动态调用 $model->disableAutoUpload() 时已禁用自动上传,设置 protected $autoUploadImages = false;。您还可以通过调用 $model->setImagesField(['cover' => ['auto_upload' => false]]) 为特定字段禁用它。否则,由于自动上传在模型保存时将覆盖它们,您将看不到您的手动上传。
$model->uploadImage($imageFile, $field = null) / $model->uploadFile($docFile, $field = null)
为给定的 $field 上传图像/文件,如果 $field 为空,则上传到数组中定义的第一个图像/文件选项。
$user = User::findOrFail($id); $user->uploadImage(request()->file('cover'), 'cover'); $user->uploadFile(request()->file('resume'), 'resume');
$model->setImagesField($fieldsOptions) / $model->setFilesField($fieldsOptions)
您也可以通过调用 $model->setImagesField($fieldsOptions) / $model->setFilesField($fieldsOptions) 并传递字段选项动态设置图像/文件字段,这将替换模型属性上定义的字段。
$user = User::findOrFail($id); $fieldOptions = [ 'cover' => [ 'width' => 1000 ], 'avatar' => [ 'width' => 120, 'crop' => true ], ]; // override image fields defined on model $user->setImagesField($fieldOptions); $fileFieldOption = [ 'resume' => ['path' => 'resumes'] ]; // override file fields defined on model $user->setFilesField($fileFieldOption);
$model->hasImageField($field) / $model->hasFileField($field)
检查字段是否定义为图像/文件字段。
$model->deleteImage($filePath) / $model->deleteFile($filePath)
如果存在,删除任何图像/文件。
$model->resizeImage($imageFile, $fieldOptions)
如果您已有图片,可以使用此方法通过与我们用于图片字段的相同选项来调整图片大小。
$user = User::findOrFail($id); // resize image, it will give you resized image, you need to save it $imageFile = '/images/some-big-image.jpg'; $image = $user->resizeImage($imageFile, [ 'width' => 120, 'crop' => true ]); // or you can use uploaded file $imageFile = request()->file('avatar'); $image = $user->resizeImage($imageFile, [ 'width' => 120, 'crop' => true ]);
$model->cropTo($x, $y)->resizeImage($imageFile, $field = null)
您可以使用此 cropTo() 方法设置裁剪的 x 和 y 坐标。如果您从某种前端图片裁剪库获取坐标,这将非常有用。
$user = User::findOrFail($id); // uploaded file from request $imageFile = request()->file('avatar'); // coordinates from request $coords = request()->only(['crop_x', 'crop_y']); // resizing will give you intervention image back $image = $user->cropTo($coords) ->resizeImage($imageFile, [ 'width' => 120, 'crop' => true ]); // or you can do upload and resize like this, it will override field options crop setting $user->cropTo($coords) ->uploadImage(request()->file('cover'), 'avatar');
$model->imageUrl($field) / $model->fileUrl($field)
为指定的图片/文件字段提供上传文件 URL。
$user = User::findOrFail($id); // in your view <img src="{{ $user->imageUrl('cover') }}" alt="" /> // http://www.example.com/storage/uploads/iGqUEbCPTv7EuqkndE34CNitlJbFhuxEWmgN9JIh.jpeg
$model->imageTag($field, $attribute = '')
它为字段提供 <img /> 标签。
{!! $model->imageTag('avatar') !!}
<!-- <img src="http://www.example.com/storage/uploads/iGqUEbCPTv7EuqkndE34CNitlJbFhuxEWmgN9JIh.jpeg" /> -->
{!! $model->imageTag('avatar', 'class="float-left mr-3"') !!}
<!-- <img src="http://www.example.com/storage/uploads/iGqUEbCPTv7EuqkndE34CNitlJbFhuxEWmgN9JIh.jpeg" class="float-left mr-3 /> -->
钩子
钩子允许您应用不同的自定义或任何您希望在图片保存前后执行的逻辑。
定义类型
您可以通过指定类名来定义钩子。
protected static $imageFields = [ 'avatar' => [ 'before_save' => BlurFilter::class, ], 'cover' => [ //... ] ];
钩子类必须有一个名为 handle 的方法,该方法在钩子被触发时将被调用。intervention image 的一个实例将被传递到 handle 方法。
class BlurFilter { public function handle($image) { $image->blur(10); } }
基于类的钩子通过 laravel ioc 容器解决,这使得您可以通过构造函数注入任何依赖项。
请注意,如果您已定义具有
width或height的字段选项,您将在before和after保存钩子处理程序中获取调整大小后的图片。当然,您可以通过request()->file('avatar')在任何时间获取原始图片。
第二种钩子定义类型是回调钩子。
$user->setImagesField([ 'avatar' => [ 'before_save' => function($image) { $image->blur(10); }, ], 'cover' => [ //... ] ]);
回调将接收到 intervention image 实例参数。
钩子类型
有两种类型的钩子:before_save 和 after_save 钩子。
before_save 钩子在图片保存到磁盘之前被调用。在钩子内对 intervention image 实例所做的任何更改都将应用于输出图片。
$user->setImagesField([ 'avatar' => [ 'width' => 100, 'height' => 100, 'before_save' => function($image) { // The image will be 50 * 50, this will override the 100 * 100 $image->resize(50, 50); }, ] ]);
after_save 钩子在图片保存到磁盘后立即被调用。
$user->setImagesField([ 'logo' => [ 'after_save' => function($image) { // Create a watermark image and save it }, ] ]);
配置文件
<?php return [ /** * Default upload storage disk */ 'upload_disk' => 'public', /** * Default Image upload directory on the disc * eg. 'uploads' or 'user/avatar' */ 'upload_directory' => 'uploads', /** * Auto upload images from incoming Request if same named field or * file_input field on option present upon model update and create. * can be override in individual field options */ 'auto_upload_images' => true, /** * It will auto delete images once record is deleted from database */ 'auto_delete_images' => true, /** * Set an image quality */ 'resize_image_quality' => 80 ];
变更日志
有关最近更改的更多信息,请参阅CHANGELOG。
测试
该软件包包含一些由 Orchestra 设置的集成/烟雾测试,可以通过 phpunit 运行。
$ composer test
贡献
有关详细信息,请参阅CONTRIBUTING。
安全
如果您发现任何与安全相关的问题,请通过电子邮件lidai@jfmedier.dk联系,而不是使用问题跟踪器。
鸣谢
许可证
MIT 许可证 (MIT)。有关更多信息,请参阅许可证文件。