Dockerized PHP application runs as a Microservice to resize and crop images on the fly. Get optimised images with MozJPEG, WebP or PNG using ImageMagick, with an efficient caching system.

Project maintained by flyimg Hosted on GitHub Pages — Theme by mattgraham

Basic Usage Examples

You can see the full list of options configurable by URL params, with examples, in the URL-Options document

We put a lot of defaults in place to prevent distortion, bad quality, weird cropping and unwanted padding.

The most common URL options are:

Get an image to fill exact dimensions,h_250,c_1/


This will serve the image.

Get the path to the generated image instead of serving it

Change the first part of the path from upload to path, like so:,h_250,c_1/ will output in the body of the response:


Get an image to fit maximum dimensions,h_250/


Crop to a square and rotate 90 degrees clockwise,h_200,c_1,r_90/


Get an image with exact dimensions and low quality,h_200,c_1,q_30/


Smart Crop

Without Smart Crop


With Smart Crop Enabled,smc_1/


Get a PDF page image to fit dimensions,h_200,pg_1/


Get a video image to fit dimensions from a time duration point,h_200,tm_00:00:05/


Converting to Colorspace Gray,clsp_Gray/


Converting to Monochrome,mnchr_1/


Using width AND height

By default setting width and height together, works like defining a rectangle that will define a max-width and max-height and the image will scale proportionally to fit that area without cropping.

By default; width, height, or both will not scale up an image that is smaller than the defined dimensions.

h_300,w_300 :,w_300/

smc : smart crop

Default: false
Description: Smart cropping feature, uses python script to determine coordinates


smc_1,w_500 :,w_500/

r : rotate

Default: null
Description: Apply image rotation (using shear operations) to the image.

example: r_90, r_-180,…

r_45 :,w_400,h_400/

o : output

Default: auto
Description: Output format requested, for example you can force the output as jpeg file in case of source file is png. The default auto will try to output the best format for the requesting browser, falling back to the same format as the source image or finally with a fallback to jpg.


q : quality

int (0-100)
Default: 90
Description: Sets the compression level for the output image. Your best results will be between 70 and 95.


q_30 :

q_100 :

Refresh or re-fetch source image

rf : refresh
Default: false
Description: When this parameter is 1, it will force a re-request of the original image and run it through the transformations and compression again. It will delete the local cached copy.


Face Detection options

fc : face-crop

int Default: 0 Description: Using facedetect repository to detect faces and passe the coordinates to ImageMagick to crop.


fc_1 :


fcp : face-crop-position

int Default: 0 Description: When using the Face crop option and when the image contain more than one face, you can specify which one you want get cropped


fcp_2 :,fcp_2/


fb : face-blur

int Default: 0 Description: Apply blur effect on faces in a given image


fb_1 :


Server Options

There are some easy to setup server configurations in the config/parameters.yml file, you can see the full list of options and server configurations in the Application Options Document

Security: Restricting Source Domains

Restricted domains disabled by default. This means that you can fetch a resource from any URL. To enable the domain restriction, change in config/parameters.yml

restricted_domains: true

After enabling, you need to put the white listed domains


Security: Signature Generation

Based on this RFC Signature Generation was added to Flyimg in order to avoid DDOS attacks.

First you need to edit security_key and security_iv in parameters.yml file and add a proper values. Than any request to Fyimg app will throw an error unless it’s encrypted.

To generate the encrypted url you need to run this command:

docker exec flyimg php app.php encrypt w_200,h_200,c_1/

it’ll return something like this:

Hashed request: TGQ1WWRKVGUrZUpoNmJMc2RMUENPL2t6ZDJkWkdOejlkM0p0U0F3WTgxOU5IMzF3U3R0d2V4b3dqbG52cFRTSFZDcmhrY1JnaGZYOHJ3V0NpZDNNRmc9PQ==

Now you can request the image throw this new url:


Run Unit Tests

docker exec flyimg vendor/bin/phpunit

Generate Html Code Coverage

docker exec flyimg vendor/bin/phpunit --coverage-html build/html

How to Provision the application on

Technology stack

Abstract storage with Flysystem

Storage files based on Flysystem which is a filesystem abstraction allows you to easily swap out a local filesystem for a remote one. Technical debt is reduced as is the chance of vendor lock-in.

Default storage is Local, but you can use other Adapters like AWS S3, Azure, FTP, DropBox, …

Currently, only the local and S3 are implemented as Storage Provider in Flyimg application, but you can add your specific one easily in src/Core/Provider/StorageProvider.php. Check an example for AWS S3 here.


See for more details.

Requires: Vegeta


Latest Results:

Crop http://localhost:8080/upload/w_200,h_200,c_1/Rovinj-Croatia.jpg
Requests      [total, rate]            500, 50.10
Duration      [total, attack, wait]    9.991377689s, 9.97999997s, 11.377719ms
Latencies     [mean, 50, 95, 99, max]  19.402096ms, 12.844271ms, 54.65001ms, 96.276948ms, 135.597203ms
Bytes In      [total, mean]            5337500, 10675.00
Bytes Out     [total, mean]            0, 0.00
Success       [ratio]                  100.00%
Status Codes  [code:count]             200:500

Resize http://localhost:8080/upload/w_200,h_200,rz_1/Rovinj-Croatia.jpg
Requests      [total, rate]            500, 50.10
Duration      [total, attack, wait]    9.992435445s, 9.979999871s, 12.435574ms
Latencies     [mean, 50, 95, 99, max]  16.676093ms, 12.376525ms, 49.676187ms, 97.354697ms, 127.14737ms
Bytes In      [total, mean]            3879500, 7759.00
Bytes Out     [total, mean]            0, 0.00
Success       [ratio]                  100.00%
Status Codes  [code:count]             200:500

Rotate http://localhost:8080/upload/r_-45,w_400,h_400/Rovinj-Croatia.jpg
Requests      [total, rate]            500, 50.10
Duration      [total, attack, wait]    9.992650741s, 9.979999937s, 12.650804ms
Latencies     [mean, 50, 95, 99, max]  13.634143ms, 11.587252ms, 26.873827ms, 50.446923ms, 68.222253ms
Bytes In      [total, mean]            17609000, 35218.00
Bytes Out     [total, mean]            0, 0.00
Success       [ratio]                  100.00%
Status Codes  [code:count]             200:500



github-changes -o flyimg -r flyimg -a -k GITHUB-TOKEN --only-pulls --use-commit-body