# Slika - simple image handling for PHP

This is a library that covers only the bare basics you need when handling images:

  * resizing
  * cropping
  * rotation

It can use either PHP's libGD or a locally installed ImageMagick binary.

## Installation

Use composer

    composer require splitbrain/slika

## Usage

Simply get an Adapter from the Slika factory, run some operations on it and call `save`.

Operations can be chained together. Consider the chain to be one command. Do not reuse the adapter returned by `run()`, it is a single use object. All operations can potentially throw a `\splitbrain\slika\Exception`.

Options (see below) can be passed as a second parameter to the `run` factory. 

```php
use \splitbrain\slika\Slika;
use \splitbrain\slika\Exception;

$options = [
    'quality' => 75
];

try {
    Slika::run('input.png', $options)
        ->resize(500,500)
        ->rotate(Slika::ROTATE_CCW
        ->save('output.jpg', 'jpg');
} catch (Exception $e) {
    // conversion went wrong, handle it
}
```

Please also check the [API Docs](https://splitbrain.github.io/slika/) for details.

## Operations 

### resize

All resize operations will keep the original aspect ratio of the image. There will be no distortion.

Keeping either width or height at zero will auto calculate the other value for you.

```php
# fit the image into a bounding box of 500x500 pixels
Slika::run('input.jpg')->resize(500,500)->save('output.png', 'png');

# adjust the image to a maximum width of 500 pixels 
Slika::run('input.jpg')->resize(500,0)->save('output.png', 'png');

# adjust the image to a maximum height of 500 pixels 
Slika::run('input.jpg')->resize(0,500)->save('output.png', 'png');
```

By default, images smaller than the given dimensions are enlarged. That is not always desirable
because the quality will suffer. Pass `false` as the third parameter to disable upscaling. The
image is then never grown beyond its original size (it is returned unchanged when it already fits
into the bounding box).

```php
# fit into 500x500 but never enlarge a smaller image
Slika::run('input.jpg')->resize(500,500,false)->save('output.png', 'png');
```

### crop

Similar to resizing, but this time the image will be cropped to fit the new aspect ratio.

```php
Slika::run('input.jpg')->crop(500,500)->save('output.png', 'png');
```

Cropping also accepts the `$upscale` parameter. When set to `false` an image that is
smaller than the requested crop area is never enlarged: dimensions larger than the image
are cropped, smaller ones are left untouched, and an image that fits entirely into the
area is returned as is. This means that the output image may be smaller than the requested
crop area and might have a different aspect ratio than requested.

```php
# crop to 500x500 but never enlarge a smaller image
Slika::run('input.jpg')->crop(500,500,false)->save('output.png', 'png');
```

### rotate

Rotates the image. The parameter passed is one of the EXIF orientation flags:

![orientation flags](https://i.stack.imgur.com/BFqgu.gif)

For your convenience there are three Constants defined:


* `Slika::ROTATE_CCW` counter clockwise rotation
* `Slika::ROTATE_CW` clockwise rotation
* `Slika::ROTATE_TOPDOWN` full 180 degree rotation 

```php
Slika::run('input.jpg')->rotate(Slika::ROTATE_CW)->save('output.png', 'png');
```

### autorotate

Rotates the image according to the EXIF rotation tag if found.

```php
Slika::run('input.jpg')->autorotate()->save('output.png', 'png');
```

## Inspecting images without processing them

Sometimes you need to know what dimensions an image *would* have after a chain of operations without actually decoding pixels or calling ImageMagick — for example, to emit `<img width="…" height="…">` attributes on a page that references a resize URL.

`\splitbrain\slika\ImageInfo` mirrors the Adapter's fluent API at the dimension level. It reads only `getimagesize()` and the EXIF orientation tag, never touching the pixel data.

```php
use \splitbrain\slika\ImageInfo;

$info = new ImageInfo('input.jpg');

// on-disk state (stable regardless of chain operations)
$info->getRawWidth();       // e.g. 4000
$info->getRawHeight();      // e.g. 3000
$info->getExtension();      // 'jpeg'
$info->getOrientation();    // EXIF orientation 1..8

// the fluent chain simulates autorotate/rotate/resize/crop
// and returns the final tracked dimensions
list($w, $h) = (new ImageInfo('input.jpg'))
    ->autorotate()
    ->resize(500, 500)
    ->getDimensions();
```

This lets you predict the output of `Slika::run(...)->autorotate()->resize(500,500)`
without doing any actual image work.

## Options

Options can be passed as associatiave array as the second parameter in `Slika::run`.

The following options are availble currently:

| Option      | Default            | Description                                |
|-------------|--------------------|--------------------------------------------|
| `imconvert` | `/usr/bin/convert` | The path to ImageMagick's `convert` binary |
| `quality`   | `92`               | The quality when writing JPEG images       |
