Why would you want to use Karla
For most people who starts working with php and ImageMagick you either install the PECL extension Imagick or work directly with ImageMagick through shell_exec().
While Imagick has a much bigger feature set than Karla ever will, it is still a limited implementation of all the features available in ImageMagick's toolbox. Karla allows you to access all of ImageMagick like with the shell_exec() approach, and have focused on making some commen operations convinient.
Karla offers a subset of the functionalities that Imagick provides, but with two distinct differences which is why Karla was written:
- You can chain your arguments so your image operations are more query-like.
- You have direct access to ImageMagick's console tools in a convenient way, should you need the full power of ImageMagick.
Karla is tested and compliant with PHP 8.2, 8.3, and 8.4, with full support for both ImageMagick 6 and 7. It has a comprehensive suite of unit tests running on Linux, macOS, and Windows.
Requirements
- PHP 8.0+ (8.2+ recommended)
- ImageMagick 6.x or 7.x (automatically detected)
- PHP extensions: pcre, SPL (default in most distributions)
- shell_exec() must be enabled
Installation
Install via Composer:
composer require localgod/karla
Then use it in your code:
use Karla\Karla;
// Using static factory method (recommended - singleton pattern)
Karla::perform('/path/to/imagemagick/')->convert()->in('input.jpg')->out('output.png')->execute();
// Or instantiate directly
$karla = new Karla('/path/to/imagemagick/');
$karla->convert()->in('input.jpg')->out('output.png')->execute();
Karla uses PSR-4 autoloading and works automatically with Composer's autoloader.
Examples
The following sections illustrates common operations performed with Imagick, Karla and in the console.
Change format to png

Imagick code (to png)
$image = new Imagick();
$image->readImage('demo.jpg');
$image->setImageFormat('png');
$image->writeImage('demo.png', true);
Karla code (to png)
Karla::perform()->convert()->in('demo.jpg')->out('demo.png')->execute();
Imagemagick in console (to png)
convert "demo.jpg" "demo.png"
Resize image

Imagick code (resize)
$image = new Imagick();
$image->readImage('demo.jpg');
$image->resizeImage(200, 200, Imagick::FILTER_LANCZOS, 0.9, true);
$image->writeImage('demo-100x100.jpg', true);
Karla code (resize)
Karla::perform()->convert()->resize(100, 100)->in('demo.jpg')->out('demo-100x100.jpg')->execute();
Imagemagick in console (resize)
convert -resize 100x100\> "demo.jpg" "demo-100x100.jpg"
Change quality

Imagick code (quality)
$image = new Imagick();
$image->readImage('demo.jpg');
$image->setImageCompression(imagick::COMPRESSION_JPEG);
$image->setImageCompressionQuality(10);
$image->writeImage('demo-low.jpg');
Karla code (quality)
Karla::perform()->convert()->quality(10)->in('demo.jpg')->out('demo-low.jpg')->execute();
Imagemagick in console (quality)
convert -quality 10 "demo.jpg" "demo-low.jpg"
Crop image

Imagick code (crop)
$image = new Imagick();
$image->readImage('demo.jpg');
$image->cropImage(100, 100, 50, 50);
$image->writeImage('demo-crop.jpg');
Karla code (crop)
Karla::perform()->convert()->crop(100, 100, 50, 50)->in('demo.jpg')->out('demo-crop.jpg')->execute();
Imagemagick in console (crop)
convert -crop 100x100+50+50 +repage "demo.jpg" "demo-crop.jpg"
Mirror image vertical

Imagick code (mirror vertical)
$image = new Imagick();
$image->readImage('demo.jpg');
$image->flipImage();
$image->writeImage('demo-flip.jpg');
Karla code (mirror vertical)
Karla::perform()->convert()->flip()->in('demo.jpg')->out('demo-flip.jpg')->execute();
Imagemagick in console (mirror vertical)
convert -flip "demo.jpg" "demo-flip.jpg"
Mirror image horizontal

Imagick code (mirror horizontal)
$image = new Imagick();
$image->readImage('demo.jpg');
$image->flopImage();
$image->writeImage('demo-flop.jpg');
Karla code (mirror horizontal)
Karla::perform()->convert()->flop()->in('demo.jpg')->out('demo-flop.jpg')->execute();
Imagemagick in console (mirror horizontal)
convert -flop "demo.jpg" "demo-flop.jpg"
Grayscale image

Imagick code (grayscale)
$image = new Imagick();
$image->readImage('demo.jpg');
$image->modulateImage(100,0,100);
$image->writeImage('demo-grayscale.jpg');
Karla code (grayscale)
Karla::perform()->convert()->type('Grayscale')->in('demo.jpg')->out('demo-grayscale.jpg')->execute();
Imagemagick in console (grayscale)
convert -type Grayscale "demo.jpg" "demo-grayscale.jpg"
Sepia tone image

Imagick code (sepia)
$image = new Imagick();
$image->readImage('demo.jpg');
$image->sepiaToneImage();
$image->writeImage('demo-sepia.jpg');
Karla code (sepia)
Karla::perform()->convert()->sepia(80)->in('demo.jpg')->out('demo-sepia.jpg')->execute();
Imagemagick in console (sepia)
convert "demo.jpg" -sepia-tone 80% "demo-sepia.jpg"
Add polaroid effect to image

Imagick code (polaroid)
$image = new Imagick();
$image->readImage('demo.jpg');
$image->polaroidImage(new ImagickDraw(), 25);
$image->writeImage('demo-sepia.jpg');
Karla code (polaroid)
Karla::perform()->convert()->polaroid(-10)->borderColor('#ffffff')->background('#000000')->in('demo.jpg')->out('demo-polaroid.png')->execute();
Imagemagick in console (polaroid)
convert -polaroid -10 -bordercolor "#ffffff" -background "#000000" "demo.jpg" "demo-polaroid.png"
Rotate image 45 degrees left

Imagick code (rotate)
$image = new Imagick();
$image->readImage('demo.jpg');
$image->rotateImage(new ImagickPixel('gray'), -45);
$image->writeImage('demo-rotate.jpg');
Karla code (rotate)
Karla::perform()->convert()->rotate(-45, 'gray')->in('demo.jpg')->out('demo-rotate.png')->execute();
Imagemagick query (rotate)
convert -rotate "-45" -background "gray" "demo.jpg" "demo-rotate.png"
Do 'magic' stuff

Imagick code (magic)
//Not possible (but you can achive a similar result)
Karla code (magic)
Karla::perform()->convert()->raw('-vignette 5x65000 -gaussian-blur 20')->in('demo.jpg')->out('demo-magic.png')->execute();
ImageMagick in console (magic)
convert -vignette 5x65000 -gaussian-blur 20 "demo.jpg" "demo-magic.png"