Code Monkey home page Code Monkey logo

glide's Introduction

Glide

Latest Version Software License Build Status Code Coverage Total Downloads Source Code Author Author

Glide is a wonderfully easy on-demand image manipulation library written in PHP. Its straightforward API is exposed via HTTP, similar to cloud image processing services like Imgix and Cloudinary. Glide leverages powerful libraries like Intervention Image (for image handling and manipulation) and Flysystem (for file system abstraction).

© Photo Joel Reynolds

© Photo Joel Reynolds

Highlights

  • Adjust, resize and add effects to images using a simple HTTP based API.
  • Manipulated images are automatically cached and served with far-future expires headers.
  • Create your own image processing server or integrate Glide directly into your app.
  • Supports both the GD library and the Imagick PHP extension.
  • Supports many response methods, including PSR-7, HttpFoundation and more.
  • Ability to secure image URLs using HTTP signatures.
  • Works with many different file systems, thanks to the Flysystem library.
  • Powered by the battle tested Intervention Image image handling and manipulation library.
  • Framework-agnostic, will work with any project.
  • Composer ready and PSR-2 compliant.

Documentation

Full documentation can be found at glide.thephpleague.com.

Installation

Glide is available via Composer:

$ composer require league/glide

Testing

Glide has a PHPUnit test suite. To run the tests, run the following command from the project folder:

$ phpunit

Contributing

Contributions are welcome and will be fully credited. Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see LICENSE for more information.

glide's People

Contributors

admad avatar alexbilbie avatar barryvdh avatar bastien-phi avatar bonzai avatar duncan3dc avatar elazar avatar erikn69 avatar grahamcampbell avatar h4cc avatar jasonvarga avatar jbrooksuk avatar juukie avatar kjellknapen avatar lustmored avatar martijngastkemper avatar michaelgooden avatar mlazze avatar ncla avatar nielsvanpach avatar paolaruby avatar pascalbaljet avatar reinink avatar sebastianpopp avatar stefanbraspenning avatar synchro avatar tgalopin avatar than avatar vincentlanglet avatar wakumaku avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

glide's Issues

Add HttpAdapter Flysystem adapter

I think it would be helpful to create a custom Flysystem adapter for Glide that would allow using a website address as the source. Something like:

$source = new League\Flysystem\Filesystem(
    new League\Flysystem\Adapter\WebsiteAddress('http://example.com/img/')
),

Clearly this Flysystem adapter wouldn't be able to fulfill the entire interface. It could read, by not write, delete, etc. But still, in the context of Glide it could still be very handy.

@frankdejonge What do you think, this could work right?

Thought exercise: flood prevention

This issue is more of a thought exercise than a problem with this project...

So I'm implementing Glide for a project at work and I might have a client that will request upto 60 images from Glide at once.

I know from simple observation that slamming the server with this many requests (each of which may potentially result in a image being manipulated in some way) can take a heavy toll on the server.

Therefore I'm wondering if there are any techniques with dealing with the barrage of requests in a sane way. I know from another simple test I did that if each request is fired about a second or so apart then I can pretty much keep up with demand and deal with each request in sequence relatively quickly.

What I'm thinking is that when a request comes in it is given a "ticket number". It will then poll to see if the server can deal with that ticket number yet. When it is time it will generate the image or retrieve it from cache. Something like this:

 Client                  Server                         
+------+                +------+                        
    |                       |                           
    |        Request        |                           
    | --------------------> | +---+                     
    |                       |     |   Request given     
    |                       |     |   ticket number    
    |                       | <---+                     
    |                       |                           
    |                       | +---+                     
    |                       |     |   Poll to see if    
    |                       |     |   server is ready   
    |                       | <---+                     
    |                       |                           
    |                       | +---+                     
    |                       |     |   Generate new image
    |        Response       |     |   or retrieve from cache
    | <-------------------- | <---+               
    |                       |                           
    |                       |                           

I'm wondering if this is something I might be able to do with React?

What do you think?

Image not resizing when cache disabled (dev-master)

When using the latest cache disabling stuff in dev-master, it seems that image resizing no longer works correctly. Haven't tried any other image manipulation, but something like this:

$server = League\Glide\ServerFactory::create([
'source' => dirname($_SERVER['SCRIPT_FILENAME']) . '/uploads/resources',
'cache' => false,
]);

$server->outputImage(thumbnail.jpg', [
'w'    => '200,
'fit'  => 'crop',
'crop' => 'center'
]);

... basically results in it outputting the original image without resizing or cropping.

Turning cache back on resolves this issue.

Add ability to specify Server class in ServerFactory

Hi, i want to extend Server class in my app. But i can not create it with ServerFactory because of hardcoded classname. Can you add some option to specify Server class. Something like this:

public function getServer($class = "League\Glide\Server")
{
    $server = new $class(
        $this->getSource(),
        $this->getCache(),
        $this->getApi()
    );
    $server->setSourcePathPrefix($this->getSourcePathPrefix());
    $server->setCachePathPrefix($this->getCachePathPrefix());
    $server->setBaseUrl($this->getBaseUrl());
    return $server;
}

Image not found when it already exists

I'm getting the error League \ Glide \ Http \ NotFoundException Could not find the image. But I checked it already exists. For example:

The error says this: Could not find the image 'C:\Users\David\www\canae\public/uploads/pages/red.jpg'.

But if I paste that link into the browser, I get the image:

cake

Here's the configuration of Glide in Laravel 5 Service provider:

    $this->app->singleton('League\Glide\Server', function ($app) {
        $filesystem = $app->make('Illuminate\Contracts\Filesystem\Filesystem');

            return \League\Glide\ServerFactory::create([
                'source' => $filesystem->getDriver(),
                'cache' => $filesystem->getDriver(),
                'source_path_prefix' => public_path().'/uploads',
                'cache_path_prefix' => public_path().'/uploads/.cache'
            ]);
        });

Any idea what I'm doing wrong?

"Signature is missing"?

Hi,
I have this error
exception 'League\Glide\Http\SignatureException' with message 'Signature is missing.' in /home/devmg/public_html/laravel/vendor/league/glide/src/Http/Signature.php:43
and I can't figure out what is the problem. Can somebody help me?

Watermark feature

It would be awesome to add watermark on image with this cool library.

Focal point support

Actually does not seems possible to specify a custom centering point for resize fit/crop operations.

Some cms allow the user to specify the focus coordinates for each image.

I propose to add an argument like this focal_coords=20%:70% to say that the focal point will be at 20% x and 70% y.

Base URL option

I think it would be wise to have a base URL option when configuration the server. Quite often image routes are appended with /img/ or something similar when used within an app.

One option would be to simply modify the request path before outputting the image. For example:

$baseUrl = '/img';
$path = substr($request->getPathInfo(), 0, strlen($baseUrl));

$glide->outputImage($path, $request->query->all());

However, since this is likely to be a very common task, it might be good to offer this functionality with the package. Something like this:

$glide = Server::create([
    // other config
    'base_url' => '/img',
]);

$glide->outputImage($request);

Basically the base_url would be omitted when finding the source file. If a more complicated base url manipulation is required, it can still be done manually by simply omitting the base_url option.

Thoughts?

Impossible to overwrite ResponseFactory::create

As ResponseFactory only streams the response (StreamedResponse), where I want is just to get a Response back, because im getting the images as base64 encoded instead of downloading them.

So I think ResponseFactory in Server should be overwriteable.

Maybe with

public function __construct(FilesystemInterface $source, FilesystemInterface $cache, ApiInterface $api, ResponseFactory $reponse = null)
{
    $this->setSource($source);
    $this->setCache($cache);
    $this->setApi($api);
    $this->setResponseFactory($response);
}

And now overwrite all the calls with

ResponseFactory::create(...)

to

$this->getResponseFactory()::create(...)

New crop option: crop=fill

Cloudinary has a very useful crop type option called fill.
This allow the image to be cropped to a given size, dynamically detecting the area of the image that will fit within the requested size and using cropping the image to contain that part of it.

This is especially useful in images that might not contain a face but do contain a point of interest that might otherwise be partly cropped out.

See: http://cloudinary.com/documentation/image_transformations#crop_modes

"Create an image with the exact given width and height while retaining original proportions. Use only part of the image that fills the given dimensions. Only part of the original image might be visible if the required proportions are different than the original ones.

For example, filling a 100x150 rectangle based on the sample image:

http://res.cloudinary.com/demo/image/upload/w_100,h_150,c_fill/sample.jpg"

Worker compatible

I'm thinking Glide should be usable in a worker based configuration as well. I doesn't necessarily has to provide this functionality out of the box, but it should at least be able to facilitate it. Something like this:

Glide Server

  1. Request comes in
  2. Check if manipulated image exists
    • If yes, show it
  3. Verify that the source image exists
    • If no, trigger a 404 error
  4. Add new job
    • Either with the filename and params, or request object
  5. Show temporary image, with no cache headers

Worker

  1. Get next job
  2. Check if manipulated image exists
    • If yes, skip
  3. Verify that the source image exists
    • If no, throw exception
  4. Generate the image

Images served as text/html

Been using Glide locally in our Laravel app and everything works really well.

We just pushed the app to production using Forge, and everything that Glide generates is served as text/html. Static images outside of Glide are served with their appropriate mime type.

When using a Glide URL inside an <img /> tag, they display correctly, although still as text/html. If we view the URL in the browser directly, we just see the garbled mess you'd expect when viewing an image as text.

This is likely some sort of server configuration issue, but asking here anyway because it appears to be Glide-specific.

Any help would be appreciated.

Add device pixel ratio (DPI & DPR)

To simplify generating larger images for higher pixel density devices, it might be helpful to add an additional function to the Size manipulator. Following what Imgix does, I propose a new adding dpr function. For example:

kayaks.jpg?w=500&dpr=1.5

This can be used in conjunction with exiting responsive image JavaScript libraries, like Imager.js, or even right in your media queries.

Or, we can use dpi, which is where things seem to be going with the CSS media query resolution feature. So instead of a ratio you would provide the target DPI, such as:

kayaks.jpg?w=500&dpi=300

Thoughts?

404 response for images that work

As you can see, it has a 404 status-code, but the image is rendered..
schermafdruk 2015-04-21 23 05 33

Except for Chrome. Safari, FF and Canary do return an image, Chrome shows a broken 'image' sometimes.

$this->app->singleton('League\Glide\Server', function($app) {
    $filesystem = $app->make('Illuminate\Contracts\Filesystem\Filesystem');

    return \League\Glide\ServerFactory::create([
        'source' => $filesystem->getDriver(),
        'cache' => $filesystem->getDriver(),
        'source_path_prefix' => 'images',
        'cache_path_prefix' => 'images/.cache',
        'base_url' => 'img',
        //'max_image_size' => 1024,
    ]);
});

Is this a bug, or a misconfig?

Watermarking support

We'd love to see (and be helpful in adding, if possible) Intervention\Image's watermark support come to Glide.

I would imagine the HTTP API could be a bit of an awkward place to try and manage that, so I wonder if it's something you could configure on the ServerFactory config or something, and then either allow a watermark=true parameter or force it to always be on for those server instance requests.

Perhaps something like this?

ServerFactory::create([
    'source'    => config('glide.source'),
    'cache'     => config('glide.cache'),
    'watermark' => config('glide.watermark') // would point to /img/watermark.png or similar
]);

StackPHP integration

As suggested with @frankdejonge, it might be good to add @stackphp support to Glide, since it's primarily an HTTP based library. Also, as per @alexbilbie's suggestion, the URL signing feature could be split out as a separate middleware as well, although I'm not exactly sure how that would work.

Rethink rectangle validation

Currently the rectangle (rect) function requires the format 'width,height,x,y', and validation fails if:

  • width > image width
  • height > image height
  • x > image width
  • y > image height

The current validation simply prevents really high numbers from being set, they cannot be any larger the the original image's width or height. However, it doesn't validate if the crop is actually within the canvas. Consider a 100x100 image, with a crop of 100,100,100,100.

  • Should Glide try to validate if a crop is within the canvas?
  • Should Glide base the max width and height on the max_image_size setting, like the Size manipulator?
  • Should Glide automatically change the cropping to fit within the canvas (changing the final crop's width and height). This is what Imigix does.

Only check parameters used by Glide for signature/cache

Right now, all query parameters are checked when generating the cache or validation/creating the signature. Perhaps we could whitelist the parameters used for Glide? This would allow arbitrary query parameters to be skipped. This could happen in 3rd party libs etc, which add a timestamp to clear browser caches for example, or custom parameters (tracking?).
Right now, each (unused) parameter will create a new cache object.

I could create a PR if you want.

Suggestion for improving performance

At the moment, when a client request an image, a php process on the server must be started to transfer the image to the client.
For a low traffic website this won't be a problem, but for a high traffic site the server might get flooded with requests to transfer images.

One possible way to avoid invoking php when an image gets requested is to create the image on the path of the request url.

Let me clarify that a bit. Instead of using get parameters to specify how an image should be manipulated, a regular url should be used. Eg: https://glide.herokuapp.com/height/100/with/500/sharp/2/kayaks.jpg
If this manipulation does not already exist in cache, create it in the public folder of the server using path "/height/100/with/500/sharp/2/kayaks.jpg" and return the image via php. The next client that comes by to retrieve that manipulation won't trigger php on the server as the webserver will return the cached file on the filesystem.

I hope this suggestion is a bit clear.

Best approach to validation

Currently Glide does all validation before any image manipulations are performed. This allows for quick validation of the request without having to actually perform any manipulations. It also allows for nice error pages, that show multiple errors.

However, this has one major problem. Each individual manipulator is isolated and runs their validation blind to what other manipulators may have done before it. For example, the current Size manipulator validates an image crop against the source image size. However, it's possible that a previous manipulator changed the size already, but since no actual manipulations were performed in the validation stage, the new size is not known.

I suggest moving to an ignore/exception based error validation system. Any invalid function requests will be simply ignored, unless they absolutely cannot be, in which case an exception is thrown. This is actually how Imgix and Cloudinary both work.

Further, the current "soft" validation has issues when it comes to extending Glide. For example, the Effects manipulator triggers an error if the filter (filt) function isn't greyscale or sepia. However, an ignore based approach would allow a subsequent manipulator to fulfill that request.

In summary, I propose:

  • Remove the "soft" validation stage, validation must performed against an actual image.
  • Whenever possible, simply ignore functions that have invalid parameters.
  • If it's an error that cannot be ignored, throw an exception and stop execution.

Problem with creating a signature

I just started using Glide and I am attempting to set up signatures for the images. I believe I'm about 99% there but I'm having a problem with it.

I am doing this -

$urlBuilder = UrlBuilderFactory::create($url, 'key');

$url = $urlBuilder->getUrl('image.php', ['image' => $path, 'w' => $width, 'h' => $height]);

When doing this, the result of $parts['path'] inside the getUrl method is /image.php.

However when doing this -

SignatureFactory::create('key')->validateRequest($request);

The output of $request->getPathInfo() in validateRequest() method is just a /.

Because of this, the signatures don't match. Any idea how I can fix this?

Compliance with the IIIF Image API 2.0

As per @alexbilbie's suggestion, it may be worth investigating adding IIIF Image API 2.0 compliance to Glide. Their URI spec is as follows:

{scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format}
  • identifier - source file
  • region - crop area
  • size - target size
  • rotation - orientation
  • quality - basically effects (color, grayscale or black/white)
  • format - jpg, tif, png, gif, jp2, pdf, webp

The biggest challenge I see is that this limits Glide quite a bit, as the original intent of this spec wasn't for image manipulation:

This API was conceived of to facilitate systematic reuse of image resources in digital image repositories maintained by cultural heritage organizations. It could be adopted by any image repository or service, and can be used to retrieve static images in response to a properly constructed URI.

However, Glide could still offer compliance, albeit with only a subset of the overall feature set. We could offer a URI parser to do this work. Something like:

$glide = Glide\Factory::server([
    'source' => 'images',
    'cache' => 'cache',
]);

$parser = new Glide\UriParser\IIIF($request);

$glide->outputImage(
    $parser->filename(),
    $parser->params()
);

Add source and cache path prefix option

Currently Glide accepts an instance of League\Flysystem\Filesystem for both the source and cache options. And while this works amazing, I'm worried there are situations where it would be desirable to also define a path prefix (folder) for each. This would mostly happen in situations where you only have a single instance of League\Flysystem\Filesystem available to you.

return League\Glide\Factories\Server::create([
    'source' => $filesystem,
    'cache' => $filesystem,
    'source_path_prefix' => 'images',
    'cache_path_prefix' => 'images/.cache'
]);

Cache not created + No resize

Hi there,

What should I try when the cache images are not created, but images are being shown.
The images do not respond to any glide url parameters.
This is my setup:

use League\Glide\Server as GlideServer;
use Illuminate\Http\Request;

get('images/{path}', function(GlideServer $server, Request $request) {

   return $server->outputImage($request);

})->where('path', '.+');

The files are in public_path() . 'images/files'

Auto orientation problem

Not strictly a bug with Glide, but more a limitation of Intervention that affects Glide functionality. As mentioned in this issue Intervention can only read EXIF data if the image object is initialised with a file path (since it uses exif_read_data). Since Glide always passes in the file contents (at it is loading the image via Flysystem) this means that auto-orientation will never work as there will be no EXIF information for Intervention to use. Explicit orientation (i.e. rotate 90deg) is unaffected.

A quick and dirty fix that we have employed is to update the makeImage() method in League\Glide\Server\Server.php to write the source file to a temporary file in the system tmp/ folder and then pass that path to the API run method (with appropriate garbage collection to clear out the temporary file once it has been used):

$source = $this->source->read(
    $this->getSourcePath($request)
);

if ($source === false) {
    throw new FilesystemException(
        'Could not read the image `'.$this->getSourcePath($request).'`.'
    );
}

// Write the source to a temporary file
$tmp = tempnam(sys_get_temp_dir(), '');
$handle = fopen($tmp, "w");
fwrite($handle, $source);

try {
    $write = $this->cache->write(
        $this->getCachePath($request),
        // Pass the path to the temporary file instead of the source itself
        $this->api->run($request, $tmp)
    );
} catch (FileExistsException $exception) {
    // Cache file failed to write. Fail silently.
    // Remove the temporary file
    unlink($tmp);
    return $request;
}

// Remove the temporary file
unlink($tmp);

Happy to make a PR with this suggested change - even happier to see a more elegant solution!

output image in pdf file ?

is there a way to output (convert) an image in PDF File using this library ( it's supported in Imagick ) ?

Outputting image with a space in the filename fails when using a Request

When trying to load a file with a space (at a URL like /img/my%20file.png), it fails when using an instance of Symfony\Component\HttpFoundation\Request.

By failing, I mean we see a NotFoundException: Could not find the image my%20file.png.

public function serve($uri, \Illuminate\Http\Request $request)
{
  $server = ServerFactory::create([...]);

  // this fails:
  $server->outputImage($request);

  // this works: ($uri is 'my file.png' without the %20)
  $server->outputImage($uri, $request->query->all());
}

Both methods work when the filename has no spaces.

Browser not caching generated images (no 304)

The browser is not caching images generated by Glde.
The images are returned fine - but subsequent requests should return a 304, correct?
I'm getting 200's every time.
I'm caching in Redis (also tried the file system).

Any ideas on why this would be?

Request:

https://localhost.dev/image/resize/508/340/my-test-image.jpg

Request headers:

Host: localhost.dev
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:35.0) Gecko/20100101 Firefox/35.0
Accept: image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Cookie: _ga=GA1.2.394136034.1411593444; km_ai=2-54476; km_uq=; km_lv=x; __utma=85360902.394136034.1411593444.1413493128.1413499159.4; __utmz=85360902.1413428285.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmv=85360902.Designer|1=user-type=prospect=1; km_ni=2-54476; exp_last_visit=1418184491; exp_last_activity=1418245209; laravel_session=eyJpdiI6ImFCUVVYdjRcL0VHQkpYRUUwM3k0UHp5ZWd1NDdxY1dsOXFvOGhOa0tqdk1jPSIsInZhbHVlIjoiYzVkNzdiM1wvMnZDYytkbDA3SnJFXC9cL0dBTDVSbEdPV1p4UDE2cXJRZE5NWEowaVwvOUE4TVdzYnJQa1wvMHJSYXl4TmVDclRVTGNCSVNZc1pIcDNlaVJTQT09IiwibWFjIjoiMzczYTZkMDgwYzkwZjE5YTZkMzkxNTJhMjhmODcxZWM0YjJmZDE0NWU1ZGYwM2M4MGNlMzk2MjQzNzBmNWI1NCJ9
Connection: keep-alive
Cache-Control: max-age=0

Response headers

Cache-Control: max-age=31536000, public
Connection: keep-alive
Content-Length: 16781
Content-Type: image/jpeg
Date: Mon, 12 Jan 2015 21:31:21 GMT
Expires: Tue, 12 Jan 2016 21:31:21 GMT
Server: nginx/1.4.6 (Ubuntu)
X-Powered-By: PHP/5.5.9-1ubuntu4.5

Action method:

function resize($width, $height, $file)
{
        // Setup Glide server
        $glide = Server::create([
            'max_image_size' => 2000*2000,
            'source' => sprintf('%s', public_path()),
            'cache' => sprintf('%s/%s', storage_path(), 'cache/images'),
        ]);

        // Return image
        return $glide->outputImage(
            $file,
            [
                'w' => $width,
                'h' => $height,
                'fit' => 'crop',
            ]
        );
 }

Background colors

Right now if you convert a transparent PNG file to a jpeg, the background becomes black. A more sane default here would probably be white. However, it probably makes even more sense to just add a background color option. I'm thinking the function could be called bg. Something like:

logo.png?bg=ffffff

Cached images/files are empty when using Dropbox as source

I'm running into an issue where using Dropbox as the source is creating empty cache files.

I've tried Local, Dropbox and S3 in all combinations of source/cache. They all work except when using Dropbox as the source. I'm even able to cache to Dropbox just fine.

When Dropbox is the source, the cache files get generated in the correct place, but they contain no data.

Do you have any ideas? Please let me know what other information I can give you that'd be helpful.

Thanks!

Use source image format by default

Right now Glide automatically outputs images as jpg if no format (fm) parameter has been set. However, this isn't always ideal. For example, if you have a transparent png you may want it to remain a png. I'd like to improve this somehow. Glide can either:

  1. Default to the source image format by default, or
  2. Add a new fm option to specify using the original, ie: kayaks.jpg?fm=src

I'm sort of leaning towards the first option. That seems to be what Imgix is doing as well:

The output format to convert the image to. Valid values are jpg and png. The default value is to use the file format of the input image.

Thoughts?

Flysystem version conflict with Laravel 5

Laravel 5 currently uses Flysystem with the version set to ~1.0. This is actually a dev-master alias, meaning minimum-stability must be set to dev, which it currently is in the Laravel development branch. However, Glide requires ~0.5 of Flysystem, which causes a version conflict with Composer.

I've updated Glide to match this (6aa2b61), but did not tag a release. When Flysystem actually hits version 1.0 later this week or next week I'll remove the minimum-stability parameter and will tag the new release.

Meaning, if you're using Laravel 5 already and want to use Glide, you need to use dev-master for a week or two, otherwise you'll get version conflicts.

Cleaning up the cache

Currently Glide does not do any cache cleanup, meaning it generates manipulated images and places them into the cache file system, but it never deletes them. It's possible that over time this cache gets large and contains many unused image manipulations.

The simple solution here is to simply delete the entire cache periodically, and on small projects this is probably fine. But on larger projects it could be problematic since all image manipulations will have to be regenerated.

It would probably be good if Glide came with a CacheCleanup helper. This cleanup tool could be run every time a request is received, or it could be setup with a scheduler (probably better). Something like:

$cache = new Filesystem(new LocalAdapter('cache-folder'));
$cleanup = new CacheCleanup($cache)
$cleanup->expire(2592000); // 30 days

This approach would delete any manipulations older than 30 days. This can be determined easily use the $filesystem->getTimestamp() method.

However, this technique will not take into consideration whether they are being actively accessed or not. Using the last accessed date would be much more complicated since this information is not readily available. To do this you would need to create a data store, and save this information every time a manipulation is created. I feel this falls outside of the scope of this project. If this sort of cache cleanup is needed, developers are welcome to implement this themselves.

Add SignKey interface

Currently Glide is hard coded to use the League\Glide\SignKey. However, it would probably be better to type hint against an interface here, such as League\Glide\Interfaces\SignKey, so that the default implementation can be swapped out for something custom.

The only issue I see here is that currently Glide removes the token parameter before generating the cache filename. This is done so that the cached filename is the same, with our with the token.

It stands to reason that if someone implemented their own signing key functionality, they may not use the token parameter at all, meaning it cannot be removed when generating a filename, since it's not known. It's possible they could even use more than one parameter, depending on their particular implementation.

Begs the question, do we care? If someone enables or disabled URL signing, and by doing so invalidates all the cache, is that okay? I sort of think so.

Replace Glide\ImageRequest with HttpFoundation\Request

As per @alexbilbie's suggestion, it may be better to replace the current Glide\ImageRequest and simply use an instance of the HttpFoundation\Request object instead. I really like this idea, but it has a couple issues.

First, we need to be able to generate a hash of the request, which is used as the cache filename. This is currently done via the Glide\ImageRequest::getHash() method. However, having looked, this method is only ever called from the Glide\Server class, so the simple solution here is to simply move this method to that class.

Second, the three main server methods all accept a filename and an array of parameters:

public function outputImage($filename, Array $params)
public function getImageResponse($filename, Array $params)
public function makeImage($filename, Array $params)

This allows developers to easily provide whatever filename and parameters they want. For example, if they had a route that they wanted to manually output an image in, this would currently be trivial:

Route::get('img/users/{id}/small', function($id)
{
    $server->outputImage(
        '/users/' . $id . '.jpg',
        [
            'w' => 300,
            'h' => 400,
            'fit' => 'crop',
        ]
    );
});

This would still be possible, however it would require creating an instance of the Request object first, which could be sort of annoying, since I don't see an easy way to do this in the HttpFoundation docs. We could potentially create a factory to make this process easier. Something like:

Route::get('img/users/{id}/small', function($id)
{
    // Create new request object
    $request = new Glide\Factory::request(
        '/users/' . $id . '.jpg',
        [
            'w' => 300,
            'h' => 400,
            'fit' => 'crop',
        ]
    );

    // Output manipulated image
    $server->outputImage($request);
});

Concurrent requests for an image that has not yet been cached

During concurrent requests (even with concurrency as low as 2), if the image has not yet been cached, a FileExistsException gets thrown:

PHP Fatal error: Uncaught exception 'League\Flysystem\FileExistsException' with message 'File already exists at path: 0fb98a01effea237c106d20fc335afb1'

I discovered this race condition issue while benchmarking performance on a VM running locally using ApacheBench v2.3:

ab -n 300 -c 2 http://images.domain.tld/item/test.jpg

How to automatically orientate images?

Hi, how to automatically orientate images?

public function foobar(\League\Glide\Server $server, Request $request)
    {
        $server->outputImage($request);
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.