okaybueno/images

Laravel 包,简化了与模型关联的图像操作。

v0.0.3 2018-02-07 10:36 UTC

This package is auto-updated.

Last update: 2024-09-19 21:56:09 UTC


README

该包已停止更新,因此将不会收到任何其他更新。如果您正在使用它,请考虑迁移到其他解决方案。现在有很多其他优秀的解决方案(例如“medialibrary”),此包不再提供任何好处。

图像

一个提供轻松处理附加到模型的图像的包。

Latest Version on Packagist Software License Quality Score Total Downloads

免责声明

该包最初发布于此处 https://github.com/followloop/imaging,但由于该包的未来尚不明确,它已被分叉并在此存储库中重新工作。

目标

我们经常需要使用附加到模型的图像(如个人资料图片),实现这一过程通常相当简单:上传图像、存储它、调整大小、将缩略图和原始图像移动到云端存储等。有时事情甚至更复杂,我们必须重新调整现有图像的大小、删除旧图像等。

因此,该包的目标是提供一种整洁、简洁的方式来处理这类附加到模型的图像,允许我们以同步和异步方式存储和处理这些图像(调整大小、删除旧图像等),从而减少我们集成到项目中的工作量。

安装

  1. 通过将此包添加到您的 composer.json 或在项目文件夹中运行 composer require okaybueno/images 来安装此包。
  2. 对于 Laravel 5.5,服务提供程序会自动注册,但如果您使用 Laravel 5.4,则必须将提供程序添加到您的 config/app.php 文件中: OkayBueno\Images\ImageServiceProvider::class
  3. 通过运行 php artisan vendor:publish --provider="OkayBueno\Images\ImageServiceProvider" 发布配置文件
  4. 打开配置文件(《config/images.php》),根据您的需求配置设置。继续阅读以了解参数的含义。
  5. 准备就绪!

用法

该包提供了 5 项不同功能

  • 图像模型:您可以使用此模型建立实体中的关系。
  • 配置文件:包含磁盘、要使用的图像驱动程序和图像处理的默认设置的设置。
  • 图像服务:允许您上传、处理和删除图像。
  • 事件/监听器:允许您处理图像操作(处理、将它们移动到 CDN 等)。
  • 命令:允许您清除已删除的图像(从磁盘删除)和调整现有图像的大小。

图像模型

该模型位于 OkayBueno\Images\Models\Image。您应将此模型作为关系包含在可能包含图像的所有模型中。此模型包含两个主要函数,它们仅返回一些值

+ thumbnails( $size = NULL, $onlyPath = FALSE): 调用此函数将返回为该图像生成的缩略图。默认情况下,该函数返回所有缩略图的完整 URL。您也可以选择仅选择一个大小(第 1 个参数)或仅返回图像的路径(第 2 个参数)。

+ url(): 返回原始图像的完整 URL。

配置文件

包含使包正常工作所需配置的参数。

    /*
    |--------------------------------------------------------------------------
    | Driver for image processing
    |--------------------------------------------------------------------------
    | The driver that you want to use to process the images.
    |
    | Accepted values: 'gd', 'imagick'
    |
    */
    'driver' => 'gd',

    /*
    |--------------------------------------------------------------------------
    | Default processing settings
    |--------------------------------------------------------------------------
    | When processing an image we can apply different settings. Although for
    | each image we can apply custom settings, we still need default ones for
    | for those images where no settings are applied.
    |
    */
    'processing_settings' => [
        'maintain_aspect_ratio'     => TRUE, // accepts TRUE or FALSE.
        'prevent_upsizing'          => TRUE, // accepts TRUE or FALSE.
        'crop'                      => FALSE, // accepts TRUE or FALSE.
        'extension'                 => 'png', // accepts jpg, png, gif, bmp, etc.
        'quality'                   => 90 // accepts any integer between 0 and 100.
    ],

    /*
    |--------------------------------------------------------------------------
    | Local disk name
    |--------------------------------------------------------------------------
    |
    | All images are first uploaded/stored in your local disk, so please
    | specific the name of disk you want to use for this.
    |
    | You can add more disks in config/filesystems.php
    |
    */
    'local_disk_name' => 'local',

    /*
    |--------------------------------------------------------------------------
    | Local disk URL
    |--------------------------------------------------------------------------
    |
    | When the image is not moved to the cloud yet, it still needs to be
    | served, so please specify here the full URL to the base folder
    | where you store the uploaded images in your local disk.
    */
    'local_disk_url' => 'http://temporal-url',

    /*
    |--------------------------------------------------------------------------
    | Cloud disk URL
    |--------------------------------------------------------------------------
    |
    | After one image is uploaded and processed, it can be moved to the cloud.
    | To do so, besides wiring up the events and listeners, you have to
    | specify a cloud disk here. If you do not want to use a cloud disk,
    | just leave this empty.
    |
    | You can add more disks in config/filesystems.php
    |
    */
    'cloud_disk_name' => '',

    /*
    |--------------------------------------------------------------------------
    | Cloud disk URL
    |--------------------------------------------------------------------------
    |
    | Same as local disk URL, but for the cloud. This URL will be used
    | once (and if) the images have been moved to the cloud.
    |
    */
    'cloud_disk_url' => '',

图像服务

图像服务绑定到位于 OkayBueno\Images\Services\ImageServiceInterface 的接口。服务包含以下功能

    /**
     * Finds an Image via the given ID, and returns an Image instance or an array with the errors.
     *
     * @param int $imageId ID of the image to find.
     * @return mixed Image instance if success, array otherwise.
     */
    public function findImageById( $imageId );
    
    /**
    * Creates a new Image in the system.
    *
    * @param mixed $imageDataOrImageURL Anything that can create an image on the Intervention's make() function.
    * @param array $options Array of options when creating the image. The options can be:
    *                  - path => Path where the image needs to be stored.
    *                  - sizes => Associative array of sizes that this image needs to be resized to.
    *                  - type => If the image belongs to a certain type, add it here. Useful to segregate.
    *                  - maintain_aspect_ratio => If set to true, it will respect the aspect ratio of the image. Default: TRUE.
    *                  - prevent_upsizing => Id set to true, the image won't be upsized (no quality loss). Default: TRUE.
    *                  - crop => You can crop the image instead of resize it. To do so, set this to true. Default: FALSE.
    *                  - extension => Extension you want to save the processed files with. Default: 'jpg',
    *                  - quality => Quality of the generated images after processing. Default: 90
    * @return mixed array or false in case of error, instance of the Image, in case of success.
    */
    public function createImage( $imageB64OrUploadedFile, array $options = [] );
    
    /**
     * Deletes (soft deletes) an image from the database
     *
     * @param int $imageId Id of the image to delete.
     * @param bool|true $skipValidation If this is set to true, the validation will be skipped and the function won't
     * check if the entity exists in the DB.
     * @return mixed true if success, array with error otherwise.
     */
    public function deleteImage( $imageId, $skipValidation = TRUE);
    
    /**
     * Processes an image stored in the local disk, and resizes it to the given sizes.
     *
     * @param mixed $imageIdOrImage ID of the image, or instance of the image to process.
     * @param array $sizes associative array with the sizes that the image needs to be resized to.
     * @return mixed Image instance.
     */
    public function processImage( $imageIdOrImage, array $sizes = [] );
    
    /**
     * Destroy an image (and its thumbs) from the disks and from the DB. It cannot be reverted.
     *
     * @param mixed $imageIdOrImage ID or instance of the image to destroy.
     * @return mixed true if success, array with errors otherwise.
     */
    public function destroyImage( $imageIdOrImage );

事件 / 监听器

包含一些事件和监听器

事件

OkayBueno\Images\Events\ImageWasCreated: 当新图像成功上传并创建在数据库/本地磁盘时触发。
OkayBueno\Images\Events\ImageWasProcessed: 当图像被处理且缩略图生成(本地)时触发。
OkayBueno\Images\Events\ImageWasMovedToCloud: 当图像(及其所有缩略图)移动到云盘时触发。
OkayBueno\Images\Events\ImageWasDeleted: 当图像被删除(软删除)时触发。

===========

监听器

OkayBueno\Images\Listeners\ProcessImageAsync: 异步处理接收到的图像(排队)。它可以订阅 ImageWasCreated 事件。
OkayBueno\Images\Listeners\ProcessImageSync: 同步处理接收到的图像(不排队)。它可以订阅 ImageWasCreated 事件。
OkayBueno\Images\Listeners\MoveProcessedImagesToCloudImageAsync: 异步(排队)将处理后的图像及其缩略图移动到云盘。它可以订阅 ImageWasProcessed 事件。
OkayBueno\Images\Listeners\MoveProcessedImagesToCloudImageSync: 同步(不排队)将处理后的图像及其缩略图移动到云盘。它可以订阅 ImageWasProcessed 事件。
OkayBueno\Images\Listeners\RemoveLocalImageAsync: 异步(排队)删除接收到的图像的本地文件。它可以订阅 ImageWasMovedToCloud 事件。
OkayBueno\Images\Listeners\RemoveLocalImageSync: 同步(不排队)删除接收到的图像的本地文件。它可以订阅 ImageWasMovedToCloud 事件。

要配置它们,只需将它们添加到您的 EventServiceProvider,位于 app/Providers/EventServiceProvider.php

如您所见,存在异步和同步事件。根据需要仅订阅其中之一。

命令

包含2个命令,可帮助您维护图像。

php artisan images:purge-deleted-images {--days=30}

删除所有已删除 --days 或更多天(默认30天)的图像,并从数据库和本地及远程磁盘中销毁它们。

php artisan images:resize {--image-id=} {--image-type=} {--sizes=}

将给定的图像(通过 -image-id)或给定的图像组(通过 --image-type)调整为新大小,这些大小通过 --sizes 提供。

注意:--sizes 应包含所有大小,而不仅仅是新大小。所有其他不在此参数中存在的图片版本都将被删除。此参数应具有以下结构:"big:500x500,small:100x100,medium:x250"。

实际示例

假设您有一个包含个人头像的用户实体。您应该像这样包含与 Image 实体的关系

public function profile_picture()
{
    return $this->hasOne( \OkayBueno\Images\Models\Image::class, 'id', 'profile_picture_id' );
}

每当您需要更新图像时,您需要使用提供的 Image 服务。我们建议您同时处理图像创建和旧图像删除,这样您可以保持图像更新并同步。以下是一个函数示例

protected function createAndSaveProfilePictureForUser( $image, User $user )
{
    if ( $image )
    {
        $prefix = substr( $user->uuid , 0, 3);
        $options = [
            'sizes' => [
                'large' => '600x600',
                'medium' => '300x300',
                'small' => '100x100'
            ],
            'path' => sprintf( 'users/%s/%s/%s/', $prefix, $user->uuid, (string)date('dmY') ),
            'crop' => TRUE,
            'extension' => 'png'
        ];

        $imageResult = $this->imageService->createImage( $image , $options );

        if ( $imageResult instanceof Image )
        {
            $saveData = [
                'picture_id' => $imageResult->id
            ];

            // Remove other image from post.
            $userPictureId = $user->picture_id;
            if ( $userPictureId ) $this->imageService->deleteImage( $userPictureId, TRUE );

            $this->usersRepository->updateBy( $saveData, $user->id );

            $user = $this->usersRepository->findOneBy( $user->id );

            return $user;
        }

        return $imageResult;
    }

    return $user;
}

$image 可以是任何可以创建 Intervention Image 对象实例的东西。

然后,每当您调用您的函数来创建或更新用户时,您都可以包含此方法来更新图像

public function updateUser( User $user, array $newUserData )
{
    ... 
    
    ...
    
    if ( array_key_exists( 'profile_picture', $newUserData ) )
    {
        $user = $this->createAndSaveProfilePictureForUser( $newUserData['profile_picture'], $user );
        unset( $newUserData['profile_picture'] );
    }
    
    ... 
        
    ...
    
    return $user;
}

为了使所有这些自动运行,您的 EventServiceProvider 应该连接事件和监听器

    protected $listen = [
        'OkayBueno\Images\Events\ImageWasCreated' => [
            'OkayBueno\Images\Listeners\ProcessImageSync'
        ],
        'OkayBueno\Images\Events\ImageWasProcessed' => [
            'OkayBueno\Images\Listeners\MoveProcessedImagesToCloudImageSync'
        ],
        'OkayBueno\Images\Events\ImageWasMovedToCloud' => [
            'OkayBueno\Images\Listeners\RemoveLocalImageSync'
        ]
    ];

这样,我们正在将所有事件连接到监听器,以便

  • 一旦图像创建(E)--> 异步处理图像(L)。
  • 一旦处理完成(E)--> 异步将其移动到云(L)。
  • 一旦移动到云(E)--> 从本地磁盘删除它(L)。

当然,您可以设置这些监听器自动处理(通过在监听器名称中将 'Async' 替换为 'Sync')。

您还可以决定是否使用云磁盘,或者是否仅本地存储文件等。例如,您可以选择不将文件移动到云,并异步处理它们,在这种情况下,您将只有像这样

    protected $listen = [
        'OkayBueno\Images\Events\ImageWasCreated' => [
            'OkayBueno\Images\Listeners\ProcessImageAsync'
        ]
    ];

就是这样!简单来说:您配置事件和监听器的方式将定义文件存储的方式。

变更日志

-- 尚未发布官方版本 --

致谢

错误和贡献

  • 发现错误?这是好事(也是坏事)。请使用Github上的问题反馈给我。
  • 需要功能或有一些有趣的东西要贡献?太好了!请发起一个pull request。

待办事项

  • 自动化测试:尽管这个包已经在生产环境中使用,但目前还没有设置自动化测试...

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件