Grabs the dominant color or a representative color palette from an image. Uses PHP and GD, Imagick or Gmagick.
Grabs the dominant color or a representative color palette from an image. Uses PHP and GD, Imagick or Gmagick.
A PHP library for grabbing the dominant color or a representative color palette from an image.
It is a PHP port of the Color Thief Javascript library, using the MMCQ (modified median cut quantization) algorithm from the Leptonica library.
Extracting meaningful colors from an image unlocks a surprising range of use cases: generating dynamic themes that match a user's uploaded avatar, building visually coherent product cards from cover art, creating adaptive UI backgrounds for music or video players, or simply analyzing the dominant hues of a dataset of images.
Color Thief PHP does this for you, without any manual color-picking, and returns results in the color format that suits
you: hex, CSS rgb(), HSL, OKLCH, CMYK, or a plain integer. You can ask for a single dominant color, a ranked palette
of up to 20 colors, or semantic swatches (Vibrant, Muted, DarkVibrant, etc.).
The recommended way to install Color Thief is through Composer:
composer require ksubileau/color-thief-phpAll functionality is exposed through the ColorThief\ColorThief class. Instantiate it once and reuse it across multiple
images.
use ColorThief\ColorThief;
$thief = new ColorThief();
$sourceImage = '/path/to/image.jpg';
$color = $thief->getColor($sourceImage);
echo $color->toCss(); // "rgb(98, 42, 131)"
echo $color->toHex('#'); // "#622a83"
getColor() returns a RgbColor object (or null if no color could be extracted), with a set of utility methods to
get the color representation that suits you.
$palette = $thief->getPalette($sourceImage);
foreach ($palette as $color) {
echo $color->toHex('#') . "\n";
}
// #622a83
// #d4a832
// #1e6b4a
// ...getPalette() returns a ColorPalette object, which is countable, iterable, and array-accessible. Colors are ordered
from most to least dominant.
$swatches = $thief->getSwatches($sourceImage);
echo $swatches->vibrant?->toHex('#'); // e.g. "#e03c7d"
echo $swatches->darkVibrant?->toHex('#'); // e.g. "#7b1c2e"
echo $swatches->muted?->toHex('#'); // e.g. "#b07a92"getSwatches() classifies the palette colors into up to six named roles: vibrant, muted, darkVibrant,
darkMuted,
lightVibrant, and lightMuted. Each property holds an RgbColor or null if no palette color matched that role.
All three methods accept the same types for the $sourceImage parameter:
'/path/to/image.jpg' (You must ensure that the path is sanitized before calling ColorThief)\GdImage)Note: Loading images from URLs is no longer supported in v3. If you need to process a remote image, fetch it yourself before passing the content to Color Thief (see Migrating from v2 to v3).
Every method returns RgbColor objects (or collections of them), with a rich set of chainable conversion and utility
methods.
…Available conversion targets from any color object: toRgb(), toOklch(), toHsl(), toHsv(), toCmyk().
ColorPalette mirrors the same conversion methods, applied to all colors at once:
…All configuration is passed to the ColorThief constructor. Every parameter is optional and falls back to a sensible
default:
| Option | Type | Default | Description |
|---|---|---|---|
quality |
int |
10 |
Pixel sampling rate. 1 analyzes every pixel (highest quality, slowest), 10 samples every 10th pixel. |
whiteThreshold |
int |
250 |
Pixels with R, G, and B all above this value are ignored. Set to 255 to disable white filtering |
alphaThreshold |
int |
125 |
Pixels with alpha below this value are ignored (0 = fully transparent, 255 = fully opaque). Set to 0 to include transparent pixels |
minSaturation |
float |
0 |
Pixels with HSV saturation below this ratio (0–1) are ignored. Set to 0 to disable |
colorSpace |
ColorSpace |
ColorSpace::Oklch |
Color space used for internal quantization. ColorSpace::Oklch produces perceptually uniform palettes. |
preferredAdapter |
AdapterInterface|string|null |
null |
Force using a specific image adapter: 'Gd', 'Imagick', 'Gmagick', or a custom AdapterInterface instance. Default null value means automatically choosing an available adapter |
with()ColorThief instances are immutable. If you need different settings for a specific call without affecting the base
configuration, use with() by calling it with named arguments. It accepts the exact same parameters as the constructor
and returns a new instance with
only the specified options overridden. The original instance is left unchanged.
$thief = new ColorThief(quality: 10, minSaturation: 0.05);
// Faster extraction, keeping all other settings
$palette = $thief->with(quality: 50)->getPalette('/path/to/image.jpg');
// Stricter filtering for a single call
$color = $thief->with(whiteThreshold: 230, minSaturation: 0.1)->getColor('/path/to/image.jpg');// Include near-white pixels (useful for images where white is meaningful)
$thief = new ColorThief(whiteThreshold: 255);
// Exclude semi-transparent pixels more aggressively
$thief = new ColorThief(alphaThreshold: 200);
// Discard gray and low-saturation pixels to focus on vivid colors
$thief = new ColorThief(minSaturation: 0.15);Use ImageRegion to analyze only a rectangular crop of the image:
use ColorThief\ImageRegion;
// Crop starting at (50, 100), 200 px wide and 150 px tall
$region = new ImageRegion(x: 50, y: 100, width: 200, height: 150);
// Or: from (50, 100) to the right/bottom edges of the image
$region = new ImageRegion(x: 50, y: 100);
$color = $thief->getColor('/path/to/image.jpg', region: $region);
$palette = $thief->getPalette('/path/to/image.jpg', region: $region);ColorThiefnew ColorThief(
int $quality = 10,
int $whiteThreshold = 250,
int $alphaThreshold = 125,
float $minSaturation = 0,
ColorSpace $colorSpace = ColorSpace::Oklch,
AdapterInterface|string|null $preferredAdapter = null,
)getColor(mixed $sourceImage, ?ImageRegion $region = null): ?RgbColor
Returns the single most dominant color, or null if the image yields no usable pixels.
getPalette(mixed $sourceImage, int $colorCount = 10, ?ImageRegion $region = null): ColorPalette
Returns a palette of dominant colors (2–20). Colors are ordered most to least dominant.
getSwatches(mixed $sourceImage, ?ImageRegion $region = null): ColorSwatches
Returns semantic swatches classified into six named roles: Vibrant, Muted, DarkVibrant, DarkMuted, LightVibrant, and
LightMuted.
with(...): self
Returns a new ColorThief instance with the specified options overridden. All arguments are optional and default to the
current instance's setting.
ColorPaletteAn immutable, ordered, array-accessible collection of color objects.
| Method | Returns | Description |
|---|---|---|
count() |
int |
Number of colors in the palette |
isEmpty() |
bool |
True if the palette has no colors |
toRgb() |
ColorPalette |
Convert the palette to sRGB colorspace |
toOklch() |
ColorPalette |
Convert the palette to OKLCH colorspace |
toHsl() |
ColorPalette |
Convert the palette to HSL colorspace |
toHsv() |
ColorPalette |
Convert the palette to HSV colorspace |
toCmyk() |
ColorPalette |
Convert the palette to CMYK colorspace |
toArray() |
list |
Component arrays in current colorspace |
toInt() |
list |
Packed RGB integers |
toHex(string $prefix = '') |
list |
Hex strings, e.g. ["#622a83", ...] |
toCss() |
list |
CSS strings using the colorspace's native notation |
toString() |
list |
String representation of each color in its current colorspace |
map(callable $fn) |
array |
Apply a callback to each color |
reduce(callable $fn, $initial) |
mixed |
Reduce palette to a single value |
ColorPalette implements ArrayAccess, Countable, and IteratorAggregate, so it supports foreach, count(), and
$palette[0] access.
All color classes (RgbColor, HslColor, HsvColor, OklchColor, CmykColor) share these
members.
| Method | Returns | Description |
|---|---|---|
population() |
int |
Pixel count this color represents in the source image (among the sampled pixels) |
proportion() |
float |
Fraction of analyzed pixels (0-1) |
| Method | Returns | Description | |--------
No open issues yet, or sync has not completed.