Skip to content

Public API reference ​

This reference describes Solo Image 1.0: PHP 8.3+, the gd and exif extensions and the Solo\Image namespace. Getting started walks through the common tasks, and Behavior in detail explains the rules below.

The public API consists of five types and the exceptions. Image, EncodedImage, Limits and Optimizer are final and readonly. Classes under Solo\Image\Internal are implementation details and can change in any release. Exception messages are not part of the compatibility promise.

TypeRole
ImageA decoded still image: its size, resized and fitted copies and encoding
EncodedImageEncoded bytes with their format and pixel dimensions
FormatThe formats that can be read and written: JPEG, PNG and WebP
LimitsThe largest input, in bytes and in pixels, that will be decoded
OptimizerRe-encodes an image and offers the result only when it is smaller
Exception\ImageExceptionBase of every failure caused by the image

Image ​

An image is created with fromBytes() only. It is immutable: no method changes its pixels.

fromBytes() ​

php
public static function fromBytes(string $bytes, Limits $limits = new Limits(), bool $firstFrame = false): self

Decodes JPEG, PNG or static WebP, detected from the contents, and applies the EXIF orientation. With $firstFrame, an animated PNG or WebP is decoded as its first frame instead of being refused: the default image of a PNG, or the first frame of a WebP on a transparent canvas of the animation's size. It refuses input for these reasons:

ReasonException
The input is longer than $limits->maxBytesImageTooLargeException
The bytes are empty or not a recognizable imageInvalidImageException
The image is not JPEG, PNG or WebPUnsupportedFormatException
A PNG or WebP container is cut shortInvalidImageException
The PNG or WebP is animated, and $firstFrame is falseAnimatedImageException
An animated WebP has no frame, or its first frame is cut short, has no image data, is not the size it declares or lies outside the canvasInvalidImageException
Width × height is more than $limits->maxPixelsImageTooLargeException
GD is built without the codec for this formatUnsupportedFormatException
GD cannot decode the pixelsInvalidImageException

The byte limit is checked before anything is parsed, and every reason but the last is found from headers and chunk boundaries, before a raster is allocated. When several reasons apply to one input, which of them is reported is not part of the contract.

width() and height() ​

php
public function width(): int
public function height(): int

The size in pixels after orientation: a photo stored sideways with an EXIF rotation reports the size it is displayed at.

resize() ​

php
public function resize(?int $width = null, ?int $height = null, bool $fast = false): self

Returns an image that fits within the bounds, with the aspect ratio kept. With one bound, the other side follows from the aspect ratio. With two, the image fits inside the box. A side is never enlarged; the derived side is rounded down and is at least one pixel.

By default every source pixel is averaged into the result, weighted by its opacity. With $fast, an image decoded from JPEG is resized with GD's bilinear scaler, which reads four source pixels per result pixel: faster, but grainier and larger once encoded. $fast is ignored for images decoded from PNG or WebP, which can be transparent, even when they happen to be opaque, and for results of contain() with margins.

When the image already fits, the same instance is returned. Otherwise the result has its own pixels and the source is unchanged.

Throws InvalidArgumentException when both bounds are null or a bound is less than 1. Throws ImageException when GD cannot allocate or resample the result.

contain() ​

php
public function contain(int $width, int $height, bool $upscale = true): self

Returns an image of exactly $width × $height. The picture is scaled to fit inside with the aspect ratio kept, following the rounding of resize(), and centred; the margins are transparent. When the margins are uneven, the extra pixel goes to the right or the bottom. With $upscale, a picture smaller than the canvas is enlarged until a side meets it; without, it keeps its size.

An image that already has the size is returned as is. A result with margins counts as transparent: encoded as JPEG the margins are white, and as PNG it has an alpha channel.

Throws InvalidArgumentException when a side is less than 1, and ImageException when GD cannot allocate or resample the result.

encode() ​

php
public function encode(Format $format = Format::Webp, int $quality = 82): EncodedImage

Encodes the pixels and returns them with the format and dimensions.

FormatQualityTransparency
Format::Jpeg0 to 100Composited on white
Format::PngNot used: lossless, compression level 6Kept
Format::Webp0 to 100, always lossyKept

No metadata of the source is written. The call does not touch PHP's output buffer.

Throws InvalidArgumentException when $quality is outside 0 to 100, for every format. Throws UnsupportedFormatException when GD is built without the codec, and ImageException when encoding fails, for example for a WebP wider or higher than 16383 pixels.

EncodedImage ​

The result of Image::encode() and Optimizer::optimize(). Applications receive it and do not construct it.

MemberTypeMeaning
$bytesstringThe encoded image
$formatFormatThe format that was encoded
$width, $heightintPixel dimensions
size()intLength of $bytes
mimeType()stringimage/jpeg, image/png or image/webp
extension()stringjpg, png or webp, without a dot

Format ​

A string-backed enum whose values are MIME types.

CaseValueextension()
Format::Jpegimage/jpegjpg
Format::Pngimage/pngpng
Format::Webpimage/webpwebp
php
public function mimeType(): string
public function extension(): string

mimeType() returns the case's value. As with any backed enum, Format::tryFrom('image/webp') turns a MIME type into a case, or null for a type that is not supported.

Limits ​

php
public function __construct(
    public int $maxBytes = 20_971_520,
    public int $maxPixels = 20_000_000,
)

The largest encoded input, in bytes, and the largest source image, in pixels, that will be decoded. Values equal to a limit are allowed. The pixel limit applies to the source, however small the requested result is.

Throws InvalidArgumentException when a limit is less than 1.

Optimizer ​

__construct() ​

php
public function __construct(Limits $limits = new Limits())

The limits apply to every image the optimizer is given.

optimize() ​

php
public function optimize(
    string $bytes,
    Format $format = Format::Webp,
    int $quality = 82,
    ?int $maxWidth = null,
    ?int $maxHeight = null,
    bool $fast = false,
): ?EncodedImage

Decodes $bytes, resizes within the bounds when at least one is given, with $fast as Image::resize() takes it, and encodes. Animated input is always refused. Returns the result when it is strictly smaller than $bytes, and null otherwise.

null says only that the candidate was not smaller. The input may be in another format or larger than the bounds.

Throws everything Image::fromBytes(), Image::resize() and Image::encode() throw. Input that cannot be processed is never reported as null.

Exceptions ​

All of them live in Solo\Image\Exception.

ExceptionExtendsThrown when
ImageExceptionRuntimeExceptionGD cannot allocate, resize or encode an image. Also the base of the rest.
InvalidImageExceptionImageExceptionThe bytes are not an image, a container is cut short or the pixels cannot be decoded
UnsupportedFormatExceptionImageExceptionThe format is not JPEG, PNG or WebP, or GD lacks its codec
AnimatedImageExceptionImageExceptionA PNG or WebP is animated and its first frame was not asked for
ImageTooLargeExceptionImageExceptionThe input is over the byte or the pixel limit

Invalid arguments raise PHP's InvalidArgumentException, which is not an ImageException.

MIT licensed.