makeabledk/laravel-cloud-images

v4.0.0 2024-01-19 13:31 UTC

README

Latest Version on Packagist Build Status StyleCI

此包通过 Laravel 便捷地管理 Google App Engine 图像 API。

图像 API 允许您一次性将图像上传到您的 GCS 存储桶,之后只需请求图像 URL 中的指定大小即可生成无限量的缩略图。无需延迟、存储问题或重新生成命令。

重要

请访问 https://github.com/makeabledk/appengine-php-imageserver 了解更多关于图像 API 和如何为您的项目设置图像服务器的信息。

此包假定您已经配置了 App Engine 图像服务器和 GCS 存储桶。

安装

您可以通过 composer 安装此包

composer require makeabledk/laravel-cloud-images

向您的 filesystems.php 配置添加一个新的 gcs 磁盘

'gcs' => [
    'driver' => 'gcs',
    'project_id' => env('GOOGLE_CLOUD_PROJECT_ID', 'your-project-id'),
    'key_file_path' => env('GOOGLE_CLOUD_KEY_FILE', '/path/to/service-account.json'), 
    'bucket' => env('GOOGLE_CLOUD_STORAGE_BUCKET', 'your-bucket'),
],

有关配置 filesystems.php 的详细信息,请参阅 https://github.com/spatie/laravel-google-cloud-storage

创建 Google 服务帐户

您可以通过以下步骤创建服务帐户密钥文件

  • 前往您的项目 Google Cloud Console 并定位到 IAM -> 服务帐户
  • 创建一个具有适当名称的新服务帐户,例如 sa-PROJECT-NAME-webapp-ENVIRONMENT
  • 在第二步中,系统会提示您授权权限。您至少应授予 存储对象管理员 权限
  • 最后,您应该 创建密钥 并下载一个 json 密钥文件。将其放置在您的 storage 文件夹中,并在 filesystems.php 中相应地设置路径

从 0.16.x 升级到 0.17.0

此版本引入了用于响应式图像的新数据库字段。请发布迁移并可选地生成占位符。

php artisan vendor:publish --provider="Makeable\CloudImages\CloudImagesServiceProvider"
php artisan migrate
php artisan cloud-images:placeholders

从 2.x 升级到 3.x

从版本 3 开始,此包使用 spatie/laravel-google-cloud-storage 而不是 superbalist/laravel-google-cloud-storage

基本用法

上传图像

轻松上传一个 \Illuminate\Http\File\Illuminate\Http\UploadedFile 到您的 GCS 存储桶,并为它创建一个图像 URL。

$file = request()->file('image'); // assuming you uploaded a file through a form
$uploaded = \CloudImage::upload($file); // filename will be a hash of the uploaded file
$uploadedToPath = \CloudImage::upload($file, 'path/filename.jpg'); // optionally specify path and filename yourself
        
echo $uploaded->url; // imageserver url, eg: http://lh3.googleusercontent.com/...
echo $uploaded->path; // path in bucket

删除图像

使用 delete 方法将同时删除存储桶文件并销毁服务图像 URL。

\CloudImage::delete('path/filename.jpg');

请注意,图像服务 URL 可能需要 24 小时才能从缓存中清除

亮点:动态生成图像

现在,我们的图像由 Google 提供,我们可以在其上动态操作。

要开始操作图像,只需一个 ImageFactory 实例即可。

$image = \CloudImage::upload($file)->make();
// or ...
$image = new \Makeable\CloudImages\ImageFactory($url); 

包含最大维度

$image->maxDimension(150)->get();

示例结果

Example image 1

裁剪到特定尺寸

$image->crop(300, 100)->get(); // Crop from top
$image->cropCenter(300, 100)->get(); // Crop from center

示例结果

Example image 1

Example image 2

拉伸到特定尺寸

$image->scale(300, 100)->get(); 

示例结果

Example image 1

模糊

$image->blur(15)->get(); // Blur 15% 

示例结果

Example image 1

自定义参数(高级)

如果您需要的功能包中没有提供,您可以指定自己的兼容 Google 的参数

$image->original()->param('fv')->get(); // This image will be flipped vertically

Example image 3

查看我们的makeabledk/appengine-php-imageserver 代码库以获取有关可用参数的更多信息。

媒体库使用(推荐)

到目前为止的示例中,没有必要发布任何迁移。您完全可以使用此包仅用于上传和从Google检索图像文件。

然而,虽然上传和提供图像很好,但您可能需要在数据库中存储引用并将它们附加到某些现有模型。

此包可能为您提供处理应用程序中图像所需的大部分功能。

扩展安装

1. 安装rutorika/sortable包,用于跟踪排序顺序(必需)

composer require rutorika/sortable

2. 安装intervention/image以读取和存储图像上的EXIF数据(可选)

composer require intervention/image 

3. 发布并运行迁移

php artisan vendor:publish --provider="Makeable\CloudImages\CloudImagesServiceProvider"
php artisan migrate

上传图像

$image = \Makeable\CloudImages\Image::upload($file); // returns a persisted Image model instance (eloquent)

echo $image->path; // bucket path
echo $image->url; // image-serving url
echo $image->meta; // exif data 

带有多个图像的模型附件

首先,在父模型上使用HasImages特征。

class Product extends Eloquent
{
    use Makeable\CloudImages\HasImages;
}

现在您有一个可以像通常一样使用的images()多对多关系

Product::first()->images()->attach(Image::first());

排序附加图像

图像将保持您附加它们的顺序。然而,您可以在之后重新排序它们。

$product = Product::first();
$images = $product->images; // In this example we assume a collection of a few images

$product->images()->moveBefore($images->get(2), $images->first());

查看rutorika/sortable包中的可排序多对多部分。

带有单个图像的模型附件

如果您的模型预期只有一个图像,则可以使用同一HasImages特征提供的方便的image()辅助程序。

class Product extends Eloquent
{
    use Makeable\CloudImages\HasImages;
}
// Always returns an Image instance - even if none uploaded
$image = Product::first()->image(); 

Image实例上,您可以使用make()方法生成所需的尺寸。

// Returns a url (string) or NULL if no image attached
$url =  $image->make()->cropCenter(500, 400)->get(); 

区分图像类型

有时您可能希望在模型上具有不同类型的“单个图像”。使用可选的tag参数来实现此行为。

Product::first()->image('featured');
Product::first()->image('cover');

注意:标记仅通过image($tag)辅助程序进行,因为rutorika/sortable包在应用order时不区分标记。

替换图像

使用Image模型上的replaceWith方法用另一个Image替换任何Image,同时保留附件。

这对于与image()辅助程序结合使用特别有用

Product::first()->image('featured')->replaceWith(Image::upload($file));
  • 如果产品没有“特色”图像,则简单地将新图像附加到它上
  • 如果产品已经有“特色”图像,则会被替换,并且删除旧图像
提示:使用eloquent mutator设置新图像
class Product extends Eloquent
{
    use \Makeable\CloudImages\HasImages;
    
    public function setImageAttribute($file)
    {
        return $this->image()->replaceWith(Image::upload($file));
    }
}
Product::first()->image = request('image'); // replace image with an UploadedFile 'image'

在控制器中,当验证和填充模型时,它会无缝工作(Laravel 5.5示例)。

public function store(Request $request)
{
    return Product::create(
        $request->validate([
            'image' => 'required|image',
            // ... some other fields
        ])
    );
}

按模型配置图像大小

通常,您希望有一些预配置的尺寸可用。在这个例子中,我们希望在我们的Product模型上有“square”和“wide”。

我们可以扩展Image模型,并在我们的Product->images()关系上使用它。

class Product extends Eloquent
{
    use \Makeable\CloudImages\HasImages;
    
    protected $useImageClass = ProductImage::class;
}
class ProductImage extends \Makeable\CloudImages\Image
{
    public function getSquareAttribute()
    {
        return $this->make()->cropCenter(500, 500)->get();
    }

    public function getWideAttribute()
    {
        return $this->make()->cropCenter(1200, 400)->get();
    }
}

现在您可以通过引用它们作为属性来访问这些尺寸。

echo Product::first()->image()->square; // single image usage
echo Product::first()->images->first()->wide; // multiple images usage

请记住将尺寸添加到$appends属性中,如果您希望它们在转换为数组时可用

class ProductImage extends Image
{
    protected $appends = ['square', 'wide'];
    
    // ...
}

在Laravel 5.5中,ApiResources是追加图像尺寸的好地方。

响应式图像

给定先前的产品图像示例,我们可以使用responsive()方法生成一组响应式图像尺寸。

通过这样做,我们可以在网站上提供优化的srcset图像。

// Returns collection of ImageFactory instances width contiously smaller images
Product::first()->image()->make()->original()->responsive()->get(); 

// Returns contents of the html srcset attribute
Product::first()->image()->make()->original()->responsive()->getSrcSet(); 

// Returns an array containing src, srcet and width attribute - especially useful for API responses
Product::first()->image()->make()->original()->responsive()->toArray(); 

// Returns <img> element with srcset attribute
Product::first()->image()->make()->original()->responsive()->toHtml(); 
(string) Product::first()->image()->make()->original()->responsive(); 

当然,所有可用的转换对于响应式图像仍然可用。

Product::first()->image()->make()->crop(500, 400)->param('fv')->responsive()->get(); 

响应式图像的方法主要受spatie/laravel-medialibrary包的启发,并提供相同的功能(包括占位符)。

请阅读他们的文档以获得关于此概念的详细解释:阅读文档

同时,请确保查看他们的演示: 响应式图像演示

最后,可以考虑查看 ResponsiveTest.php 以获取更多此包提供的使用示例。

清理旧图像

删除图像

当删除 Image 实例时,将自动调用 CloudImage::delete() 方法以删除实际的存储桶文件。

删除无附件的图像

随着时间的推移,您的 images 表可能因不再与模型附件相关的图像而变得臃肿。

使用 cloud-images:cleanup 命令删除不再使用的图像(以及实际的存储桶文件)。

php artisan cloud-images:cleanup

测试

您可以使用以下命令运行测试:

composer test

贡献

我们非常乐意接受有关附加功能的拉取请求。请参阅 CONTRIBUTING 以获取详细信息。

致谢

许可证

署名-相同 4.0 国际。请参阅 许可证文件 以获取更多信息。