Skip to content
A simple PHP library to crop, resize, rotate and watermark images
PHP Dockerfile
Branch: master
Clone or download


Darkroom is a library that facilitates simple image manipulation operations in PHP. The core functionality of the library is implemented in the form of tools which makes extending the image editor natural and intuitive.

Build Status StyleCI Maintainability Test Coverage


The Darkroom library has the following requirements:

  • PHP 5.6+
  • GD Library


Use composer to install the library in your project:

composer require darkroom/darkroom
Table of Contents

Getting Started

The library API is inspired by the options and actions that an image editor GUI would have. The result is a fluent and descriptive OOP driven API which replaces the long functions with a lot of arguments.

There are three major components you should be aware of: The Editor, Image and Tools. In a nutshell, the Editor is use to create the Image object(s) and the Tools are the actions that manipulate the image like crop and resize.

Use the editor to open an image:

$image = \Darkroom\Editor::open('image.jpg');

Simple image crop:

// 400x400 viewport
// 400x200 viewport
$image->edit()->crop()->rectagle(400, 200);

By default the image crop viewport will start from the top left of the image or the x,y position 0,0. The position of the viewport can be specified as follows:

// Crop 400x400 square at position (150, 100)
$image->edit()->crop()->square(400)->at(150, 100);

Save image to file system and get the reference:

// Save the image edits and get the local file path of the new image
$newImagePath = $image->save()->localPath();

// Save the image edits and get the public URL of the new image
$newImageUrl = $image->save()->publicUrl();

To render the image to the standard output with its corresponding HTTP headers:



Every image edit is handled by a Tool. Image edits include but are not limited to cropping, resizing placing watermarks. The library comes with built-in tools and also provides the option for custom tools to be registered

Built-in tools

All tools are accessed from the Image reference edit() factory.

$image = \Darkroom\Editor::open('image.jpg');

// The call to resize() will return an intance of \Darkroom\Tool\Resize


Crop the image using a custom viewport dimension and position.


  • rectangle( with, height ) - Creates rectangular viewport with specified dimensions
  • square( dimension ) - Creates square viewport with specified dimension
  • at( x, y ) - Position the upper left corner of the viewport.


Resize the image to different dimensions while respecting the original aspect ratio unless the distort modifier is used.


  • to( with, height ) - Set the dimensions of the new image. The height is optional.
  • heightTo( height ) - Set the height of the new image. The width will be automatically calculated.
  • by( percent ) - Set the dimensions of the new image using a decimal percentage where 0.5 is 50% or half the size of the original image.
  • withImageFill( image ) - Use an image for the unused area if the new image has a different ratio.
  • withColorFill( color ) - Use solid color for the unused area if the new image has a different aspect ratio.
  • withTransparentFill() - Makes the background of the unused area transparent.
  • distort() - Ignores the original aspect ratio and resize the image exactly to the specified dimensions.


Rotate the image either left or right based on an angle.


  • left( degrees ) - Rotate image to the left.
  • right( degrees ) - Rotate image to the Right.
  • withColorFill( color ) - Set a fill background color.
  • withTransparentFill() - Makes the background transparent.


Stamp image with another position at one or more positions. Can be use to place watermarks in images.


  • with( image ) - Sets the image to stamp with.
  • at( x, y ) - Coordinates where to stamp the image. This modifier could be call multiple times to stamp at multiple locations
  • opacity( level ) - Sets the opacity level for the stamp where 1 is opaque and 0 is transparent

Custom tools

You create your own tool or recipe by implementing the \Darkroom\Tool\Tool interface. Alternatively you can extend \Darkroom\Tool\AbstractTool which already implements the interface. You may register any amount of tools used them in the same way built-in tools are used.

// Registers a new tool which can be accesed as 'flip'
\Darkroom\Editor::registerTool('flip', '\MyApp\Image\Tool\Flip');

// Usage
$image = Editor::open('my-image.jpg');
// Use new 'flip' tool

Been able to use your own custom tools is a very powerful feature. With great power comes great responsibility. Editor::registerTool() even allows you to overwrite built-tools with your own.

The Storage

The library comes with a zero configuration built-in storage system. By default images will be saved in the folder /storage/images/ located in the document root of your application. The images will be furthered organized in a monthly folder follow by a random name. Ex: 2018-09/ad57ryht-a5gf-s5hr2AWg.jpg.

The image storage if fully customizable and can even support storage to external services like AWS S3. You may access and configure the underlying storage system with \Darkroom\Editor::config()->storage().

Location and naming pattern

Example update both the root path and the image naming pattern:

$store = \Darkroom\Editor::config()->storage();
// Updates where images will be stored

// Updates the default image naming pattern
// The new patten will generate name a string of 16 characters

In the path pattern any letter character will be process by the PHP date() function and replaced with its output. Any % follow by a number represents a random string where the number is the length of the string. Ex: %6 will generate a 6 characters long random string. The default pattern isY-m/%32.

Custom path generator

If you need even more control over how and where the images are been stored you can configure the built-in storage with a PHP callable with \Darkroom\Editor::config()->storage()->setPathGenerator(callable). The path generator callable receives and instance of the image been save as \Darkroom\Image. You may return the new absolute path where the image will be stored in the file system.

\Darkroom\Editor::config()->storage()->setPathGenerator(function($image, $basePath){
    // Saved new images using the original name suffixed with a
    return $basePath . DIRECTORY_SEPRARATOR . $image->file()->name() . '_' . microtime(true);

Sending to external service

Since the path generator has access to the Image reference it can also be used as a bridge to store the image in a separate system or storage service like AWS S3. Instead of returning a string for the local file system path you may return anything else like a boolean or a custom object and it wil be used as the return value for Image::save() calls.

// Configuration
    $buffer = $image->renderTo(tmpfile());
    // Code to upload stream to AWS S3 or other service
    // You can also return a reference to the external service like the URL or resource id as long as 
    // is wrapped in an object.         
    return true;

// Usage
Editor::open('my-image.jpg')->save(); // Returns true

Custom Storage

You should not include a lot of code in a closure to handle your custom image saving logic. If you need more room to handle saving the images consider making your own implementation of the \Darkroom\Storage\Storage interface. You can then register your Storage implementation in the editor.

// Configuration
\Darkroom\Editor::config()->useStorage(new MyCustomStore);


  • Complete the Resize tool fill modifiers.
  • Add Rotate tool to perform image rotation.
  • Implement registration system for custom tools.
  • Add unit test for the core functionality.
You can’t perform that action at this time.