PHPackages                             makeabledk/laravel-cloud-images - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [File &amp; Storage](/categories/file-storage)
4. /
5. makeabledk/laravel-cloud-images

ActiveLibrary[File &amp; Storage](/categories/file-storage)

makeabledk/laravel-cloud-images
===============================

v4.3.2(6mo ago)587.0k7[1 PRs](https://github.com/makeabledk/laravel-cloud-images/pulls)CC-BY-SA-4.0PHPPHP ^8.1CI passing

Since Nov 1Pushed 6mo ago5 watchersCompare

[ Source](https://github.com/makeabledk/laravel-cloud-images)[ Packagist](https://packagist.org/packages/makeabledk/laravel-cloud-images)[ RSS](/packages/makeabledk-laravel-cloud-images/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (11)Versions (42)Used By (0)

Laravel Cloud Images
====================

[](#laravel-cloud-images)

[![Latest Version on Packagist](https://camo.githubusercontent.com/91be5120cb645a7d52df1e4ec4ef0fde1b64a761a118b7a36b6c30ab9b0f258f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d616b6561626c65646b2f6c61726176656c2d636c6f75642d696d616765732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/makeabledk/laravel-cloud-images)[![Build Status](https://camo.githubusercontent.com/f202e1b4ef65210d43831e28fcbbfdbec8490576cacff35481a5a1db4ac3ba4f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f6d616b6561626c65646b2f6c61726176656c2d636c6f75642d696d616765732f52756e25323074657374733f6c6162656c3d5465737473)](https://github.com/makeabledk/laravel-cloud-images/actions)[![StyleCI](https://camo.githubusercontent.com/d8c960c520833501bc9dfceb92b5503c388368acd47578e85691ddbecbc71430/68747470733a2f2f7374796c6563692e696f2f7265706f732f3130393035373937382f736869656c643f6272616e63683d6d6173746572)](https://styleci.io/repos/109057978)

This package provides a convenient to manage Google App Engine Images API through Laravel.

Images API allows you to upload an image once to your GCS bucket and afterwards generate unlimited thumbnails just by requesting the specified size in the image-url. No delay, storage concerns or re-generate commands.

**Important**

Please checkout  for more information on Images API and how to setup an imageserver for your project.

This package assumes you already have a configured App Engine imageserver and GCS Bucket.

Installation
------------

[](#installation)

You can install this package via composer:

```
composer require makeabledk/laravel-cloud-images
```

Add a new `gcs` disk to your `filesystems.php` config

```
'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'),
],
```

See  for more details about configuring `filesystems.php`.

#### Creating a Google Service Account

[](#creating-a-google-service-account)

You can create a service account key file through these steps

- Head to your project's [Google Cloud Console](https://console.cloud.google.com) and locate **IAM** -&gt; **Service accounts**
- Create a new service account with an appropriate name, ie. `sa-PROJECT-NAME-webapp-ENVIRONMENT`.
- On the second step it prompts you to grant permissions. You should as a minimum grant `Storage Object Admin` permissions
- Finally you should `Create key` and download a json key file. Place it in your `storage` folder and set path in `filesystems.php` accordingly

### Upgrading from 0.16.x -&gt; 0.17.0

[](#upgrading-from-016x---0170)

This release introduces new database fields for responsive images. Please publish migrations and optionally generate placeholders.

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

### Upgrading from 2.x --&gt; 3.x

[](#upgrading-from-2x----3x)

Starting with version 3 this package uses `spatie/laravel-google-cloud-storage` instead of `superbalist/laravel-google-cloud-storage`.

- Please ensure you refer to the configuration options in [laravel-google-cloud-storage#installation](https://github.com/spatie/laravel-google-cloud-storage#installation).
- Specifically make sure you change your disk configuration in `config/filesystems.php` @ `gcs.key_file` --&gt; `gcs.key_file_path`.

Basic usage
-----------

[](#basic-usage)

### Upload an image

[](#upload-an-image)

Easily upload a `\Illuminate\Http\File` or `\Illuminate\Http\UploadedFile` to your GCS bucket and create an image-url for it.

```
$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 an image

[](#delete-an-image)

Using the `delete` method will both delete the bucket file and destroy serving-image URL.

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

Note that image-serving URL's can take up to 24 hours to clear from cache

### The good stuff: Generating images on the fly

[](#the-good-stuff-generating-images-on-the-fly)

Now that our image is served by Google, we can manipulate it on the fly.

All you have to do to start manipulating images, is an instance of `ImageFactory`:

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

#### Contain to max dimension

[](#contain-to-max-dimension)

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

Example result:

[![Example image 1](https://camo.githubusercontent.com/b020b528809993a51eca56ae42c00b96d9e0b644576c4412d3102d338194a46f/68747470733a2f2f6c68332e676f6f676c6575736572636f6e74656e742e636f6d2f6e566c47785a31476a7a5f46505f786a62715446445a7454346d4d364c70714e556c71662d465235794f70757a6659636b6f46647053363648424b564a6b554379634671503770464a6b46554b6e45383863476a355a6c4772673d73313530)](https://camo.githubusercontent.com/b020b528809993a51eca56ae42c00b96d9e0b644576c4412d3102d338194a46f/68747470733a2f2f6c68332e676f6f676c6575736572636f6e74656e742e636f6d2f6e566c47785a31476a7a5f46505f786a62715446445a7454346d4d364c70714e556c71662d465235794f70757a6659636b6f46647053363648424b564a6b554379634671503770464a6b46554b6e45383863476a355a6c4772673d73313530)

#### Crop to dimensions

[](#crop-to-dimensions)

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

Example result:

[![Example image 1](https://camo.githubusercontent.com/080269d5090cdcd2d7935bcd98221c705e42f24cb29a4267b036c0489804ccd4/68747470733a2f2f6c68332e676f6f676c6575736572636f6e74656e742e636f6d2f6e566c47785a31476a7a5f46505f786a62715446445a7454346d4d364c70714e556c71662d465235794f70757a6659636b6f46647053363648424b564a6b554379634671503770464a6b46554b6e45383863476a355a6c4772673d632d773330302d68313030)](https://camo.githubusercontent.com/080269d5090cdcd2d7935bcd98221c705e42f24cb29a4267b036c0489804ccd4/68747470733a2f2f6c68332e676f6f676c6575736572636f6e74656e742e636f6d2f6e566c47785a31476a7a5f46505f786a62715446445a7454346d4d364c70714e556c71662d465235794f70757a6659636b6f46647053363648424b564a6b554379634671503770464a6b46554b6e45383863476a355a6c4772673d632d773330302d68313030)

[![Example image 2](https://camo.githubusercontent.com/d8555e9d19c6a519f0cebf053851fe3392fa97802f2fb5320bed4056fade2817/68747470733a2f2f6c68332e676f6f676c6575736572636f6e74656e742e636f6d2f6e566c47785a31476a7a5f46505f786a62715446445a7454346d4d364c70714e556c71662d465235794f70757a6659636b6f46647053363648424b564a6b554379634671503770464a6b46554b6e45383863476a355a6c4772673d6e2d773330302d68313030)](https://camo.githubusercontent.com/d8555e9d19c6a519f0cebf053851fe3392fa97802f2fb5320bed4056fade2817/68747470733a2f2f6c68332e676f6f676c6575736572636f6e74656e742e636f6d2f6e566c47785a31476a7a5f46505f786a62715446445a7454346d4d364c70714e556c71662d465235794f70757a6659636b6f46647053363648424b564a6b554379634671503770464a6b46554b6e45383863476a355a6c4772673d6e2d773330302d68313030)

#### Stretch to dimensions

[](#stretch-to-dimensions)

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

Example result:

[![Example image 1](https://camo.githubusercontent.com/1bdfcc42aece15088335d306c68d37ecbd6357c6925154fa2f26b49bb874e416/68747470733a2f2f6c68332e676f6f676c6575736572636f6e74656e742e636f6d2f6e566c47785a31476a7a5f46505f786a62715446445a7454346d4d364c70714e556c71662d465235794f70757a6659636b6f46647053363648424b564a6b554379634671503770464a6b46554b6e45383863476a355a6c4772673d732d773330302d68313030)](https://camo.githubusercontent.com/1bdfcc42aece15088335d306c68d37ecbd6357c6925154fa2f26b49bb874e416/68747470733a2f2f6c68332e676f6f676c6575736572636f6e74656e742e636f6d2f6e566c47785a31476a7a5f46505f786a62715446445a7454346d4d364c70714e556c71662d465235794f70757a6659636b6f46647053363648424b564a6b554379634671503770464a6b46554b6e45383863476a355a6c4772673d732d773330302d68313030)

#### Blur

[](#blur)

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

Example result:

[![Example image 1](https://camo.githubusercontent.com/c9245cdd5f199447e3e1f21f4aad1d3e3104a4e9d2770254e490da20981db7dd/68747470733a2f2f6c68332e676f6f676c6575736572636f6e74656e742e636f6d2f6e566c47785a31476a7a5f46505f786a62715446445a7454346d4d364c70714e556c71662d465235794f70757a6659636b6f46647053363648424b564a6b554379634671503770464a6b46554b6e45383863476a355a6c4772673d632d773330302d683130302d66536f6674656e3d312c31352c30)](https://camo.githubusercontent.com/c9245cdd5f199447e3e1f21f4aad1d3e3104a4e9d2770254e490da20981db7dd/68747470733a2f2f6c68332e676f6f676c6575736572636f6e74656e742e636f6d2f6e566c47785a31476a7a5f46505f786a62715446445a7454346d4d364c70714e556c71662d465235794f70757a6659636b6f46647053363648424b564a6b554379634671503770464a6b46554b6e45383863476a355a6c4772673d632d773330302d683130302d66536f6674656e3d312c31352c30)

#### Custom parameters (advanced)

[](#custom-parameters-advanced)

If the functionality you need is not provided by the package, you can specify your own google-compatible parameters:

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

[![Example image 3](https://camo.githubusercontent.com/5e972ac2c56a60e1da36528cc1e92845ee1a677fa3e0eaca9390c49c173edd90/68747470733a2f2f6c68332e676f6f676c6575736572636f6e74656e742e636f6d2f6e566c47785a31476a7a5f46505f786a62715446445a7454346d4d364c70714e556c71662d465235794f70757a6659636b6f46647053363648424b564a6b554379634671503770464a6b46554b6e45383863476a355a6c4772673d6e2d773330302d683130302d6676)](https://camo.githubusercontent.com/5e972ac2c56a60e1da36528cc1e92845ee1a677fa3e0eaca9390c49c173edd90/68747470733a2f2f6c68332e676f6f676c6575736572636f6e74656e742e636f6d2f6e566c47785a31476a7a5f46505f786a62715446445a7454346d4d364c70714e556c71662d465235794f70757a6659636b6f46647053363648424b564a6b554379634671503770464a6b46554b6e45383863476a355a6c4772673d6e2d773330302d683130302d6676)

Checkout our [makeabledk/appengine-php-imageserver](https://github.com/makeabledk/appengine-php-imageserver) repository for more information on available parameters.

Media Library usage (recommended)
---------------------------------

[](#media-library-usage-recommended)

For the examples so far there has been no need to publish any migrations. You are completely free to only use this package for uploading and retrieving image files from Google.

However, while uploading and serving images is all well and good, you will likely need to store the references in your database and attach them to some existing models.

This package will likely provide you with most of the functionality you'll ever need for dealing with images in your application.

### Extended installation

[](#extended-installation)

#### 1. Install `rutorika/sortable` package which is used to track sort-order (required)

[](#1-install-rutorikasortable-package-which-is-used-to-track-sort-order-required)

```
composer require rutorika/sortable
```

#### 2. Install `intervention/image` to read and store exif-data on your images (optional)

[](#2-install-interventionimage-to-read-and-store-exif-data-on-your-images-optional)

```
composer require intervention/image
```

#### 3. Publish and run migrations

[](#3-publish-and-run-migrations)

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

### Uploading images

[](#uploading-images)

```
$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
```

### Model attachment with multiple images

[](#model-attachment-with-multiple-images)

First, use the `HasImages` trait on your parent model.

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

Now you have an `images()` belongs-to-many relationship you can utilize as you normally would:

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

#### Ordering attached images

[](#ordering-attached-images)

Images will be kept in the order you attach them. However, you are free to reorder them afterwards.

```
$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());
```

Checkout the *Sortable many to many* section of the [rutorika/sortable](https://github.com/boxfrommars/rutorika-sortable) package.

### Model attachment with a single image

[](#model-attachment-with-a-single-image)

If your model is expected to have just one image, you may use the convenient `image()` helper provided by the same `HasImages` trait.

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

```
// Always returns an Image instance - even if none uploaded
$image = Product::first()->image();
```

On the `Image` instance you may use the `make()` method to generate the size you need.

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

#### Differentiating between image types

[](#differentiating-between-image-types)

Sometimes you may wish to have different types of 'single images' on a model. Use the optional `tag` parameter to achieve this behavior.

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

Note: Tagging is only intended through the `image($tag)` helper as the `rutorika/sortable` package does not differentiate between tags when applying `order`.

#### Replacing images

[](#replacing-images)

Use the `replaceWith` method on the `Image` model to swap any `Image` with another while preserving attachments.

This is especially useful in combination with the `image()` helper:

```
Product::first()->image('featured')->replaceWith(Image::upload($file));
```

- If the product did not have a 'featured' image, it would simple attach the new one
- If the product did already have 'featured' image it would get replaced, and the old one deleted

##### Pro tip: Use an eloquent mutator to set the new image

[](#pro-tip-use-an-eloquent-mutator-to-set-the-new-image)

```
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'
```

In your controller it would work seamlessly when validating and `filling` the model (Laravel 5.5 example).

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

### Configuring image sizes per model

[](#configuring-image-sizes-per-model)

Often times you want a few pre-configured sizes available. In this example we would like 'square' and 'wide' available on our `Product` model.

We may extend the `Image` model and use that on our `Product->images()` relationship.

```
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();
    }
}
```

Now you can access the sizes simply by referencing them as properties.

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

Remember to add the sizes to `$appends` attribute if you want them available when casting to array:

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

    // ...
}
```

In Laravel 5.5, ApiResources would be a great place to append your image sizes as well.

### Responsive images

[](#responsive-images)

Given the previous example of a product image, we may use the `responsive()` method to generate a collection of responsive image sizes.

By doing this, we can serve `srcset` optimized images on our website.

```
// 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  element with srcset attribute
Product::first()->image()->make()->original()->responsive()->toHtml();
(string) Product::first()->image()->make()->original()->responsive();
```

Of course all the available transformations are still available for responsive images.

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

The approach for responsive images is heavily inspired by the [spatie/laravel-medialibrary](https://github.com/spatie/laravel-medialibrary) package and offer the same functionality (including placeholders).

Consider [reading their documentation](https://docs.spatie.be/laravel-medialibrary/v7/responsive-images/getting-started-with-responsive-images) for a very thorough explanation of the concept.

Also be sure to checkout their demo here: [Responsive images demo](https://docs.spatie.be/laravel-medialibrary/demo/responsive-images)

Finally consider checking out [ResponsiveTest.php](https://github.com/makeabledk/laravel-cloud-images/blob/master/tests/Feature/ResponsiveTest.php) for more usage examples this package offers.

### Cleaning up old images

[](#cleaning-up-old-images)

#### Deleting an image

[](#deleting-an-image)

When deleting an `Image` instance, the `CloudImage::delete()` method is automatically fired to delete the actual bucket file.

#### Deleting images with no attachment

[](#deleting-images-with-no-attachment)

Over time your `images` table may get bloated with images that no longer has model-attachments to them.

Use the `cloud-images:cleanup` command to delete images (along with the actual bucket files) that are no longer used.

```
php artisan cloud-images:cleanup
```

Testing
-------

[](#testing)

You can run the tests with:

```
composer test
```

Contributing
------------

[](#contributing)

We are happy to receive pull requests for additional functionality. Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Credits
-------

[](#credits)

- [Rasmus Christoffer Nielsen](https://github.com/rasmuscnielsen)
- Spatie for their awesome [spatie/laravel-medialibrary](https://github.com/spatie/laravel-medialibrary)
- [All Contributors](../../contributors)

License
-------

[](#license)

Attribution-ShareAlike 4.0 International. Please see [License File](LICENSE.md) for more information.

###  Health Score

55

—

FairBetter than 98% of packages

Maintenance66

Regular maintenance activity

Popularity36

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity84

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 88.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~112 days

Recently: every ~62 days

Total

27

Last Release

200d ago

Major Versions

v0.10.0 → v1.0.02019-09-30

v1.4.0 → v2.0.02022-01-26

v2.0.0 → v3.0.02022-03-09

v3.0.0 → v4.0.02024-01-19

PHP version history (6 changes)v0.1.0PHP &gt;=7.0.0

v0.7.0PHP &gt;=7.1.0

v1.3.0PHP &gt;=7.3.0

v1.4.0PHP &gt;=7.3.0|8.\*

v2.0.0PHP ^8.0

v4.0.0PHP ^8.1

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/22741894?v=4)[Makeable ApS](/maintainers/makeabledk)[@makeabledk](https://github.com/makeabledk)

---

Top Contributors

[![rasmuscnielsen](https://avatars.githubusercontent.com/u/8465957?v=4)](https://github.com/rasmuscnielsen "rasmuscnielsen (72 commits)")[![iatanasov-frt](https://avatars.githubusercontent.com/u/30825404?v=4)](https://github.com/iatanasov-frt "iatanasov-frt (4 commits)")[![larsrbak](https://avatars.githubusercontent.com/u/5303034?v=4)](https://github.com/larsrbak "larsrbak (3 commits)")[![Pederytter](https://avatars.githubusercontent.com/u/18698451?v=4)](https://github.com/Pederytter "Pederytter (1 commits)")[![RTC1](https://avatars.githubusercontent.com/u/6593835?v=4)](https://github.com/RTC1 "RTC1 (1 commits)")

---

Tags

gcs-bucketimages-apiimageserverlaravelserve-images

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/makeabledk-laravel-cloud-images/health.svg)

```
[![Health](https://phpackages.com/badges/makeabledk-laravel-cloud-images/health.svg)](https://phpackages.com/packages/makeabledk-laravel-cloud-images)
```

###  Alternatives

[unisharp/laravel-filemanager

A file upload/editor intended for use with Laravel 5 to 10 and CKEditor / TinyMCE

2.2k3.3M73](/packages/unisharp-laravel-filemanager)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)[laravel/vapor-cli

The Laravel Vapor CLI

31310.7M8](/packages/laravel-vapor-cli)[laravel-zero/framework

The Laravel Zero Framework.

3371.4M368](/packages/laravel-zero-framework)[stechstudio/laravel-zipstream

A fast and simple streaming zip file downloader for Laravel.

4633.7M3](/packages/stechstudio-laravel-zipstream)[spatie/laravel-google-cloud-storage

Google Cloud Storage filesystem driver for Laravel

2408.9M12](/packages/spatie-laravel-google-cloud-storage)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
