Color Palette Extractor: Dominant Colors from Images & Websites avatar

Color Palette Extractor: Dominant Colors from Images & Websites

Pricing

from $2.40 / 1,000 palette extracteds

Go to Apify Store
Color Palette Extractor: Dominant Colors from Images & Websites

Color Palette Extractor: Dominant Colors from Images & Websites

Extract a color palette from image URLs (JPG, PNG, WebP, GIF) with k-means or median cut, or read the colors a website's CSS uses. Hex, RGB, share, nearest color name, WCAG contrast and CSS/Tailwind snippets per item. Static fetch only, no JavaScript rendering.

Pricing

from $2.40 / 1,000 palette extracteds

Rating

0.0

(0)

Developer

Data Done Right

Data Done Right

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Security

Limited permissions

Share

This color palette extractor pulls the dominant colors out of image URLs (JPG, PNG, WebP, GIF) with k-means or median cut, and can also read the colors a website's CSS declares. Every item gets its colors as hex, RGB and HSL, each color's share, the nearest CSS color name, WCAG contrast numbers, and ready-to-paste CSS variables and Tailwind colors.

What it does not do. It does not run JavaScript or a browser: for websites it reads the static HTML, inline styles and up to 6 linked stylesheets, so colors that scripts or CSS-in-JS create at run time are missed (the row says so when nothing is found). Website percentages count how often a color is declared, not how much of the screen it covers. It does not read SVG images, screenshots of pages, PDFs or videos (see "Video Frame Extractor" for video frames), and it does not get past logins, CAPTCHAs or bot protection: a blocked site is reported as blocked.

What you get

  • One dataset row per image or website: dominantHex, dominantName, a ranked palette (hex, rgb, hsl, name, percent, readable text color, contrast on white/black), hexList, best contrastPairs.
  • cssVariables and tailwindColors blocks you can paste into a stylesheet or tailwind.config.js.
  • Websites also return themeColor, textColors, backgroundColors and customProperties (CSS variables that hold a color).
  • Bad URLs never stop the run. Failed items are free and listed in the FAILED record with the reason.

How to get the dominant colors of an image from a URL

  1. Put direct image links in imageUrls, for example https://example.com/photo.jpg.
  2. Choose colorsPerItem (default 6) and the method: kmeans (smoother, default) or median-cut (classic, favors distinct colors).
  3. Run it. palette[0] is the dominant color. Percentages add up to about 100 for an image. The same image always gives the same palette.

The image is shrunk to at most 180x180 pixels before counting,. Fully transparent pixels are ignored. Use ignoreWhite for product shots on a white background and ignoreBlack for images on black.

How to find the color palette of a website

  1. Put sites in websiteUrls, for example https://www.python.org (the https:// is added if you leave it out).
  2. The Actor fetches the page and up to 6 stylesheets once each, counts every color in color, background, border, fill, stroke and shadow declarations (hex, rgb(), hsl() and named colors), and ranks them.
  3. By default ignoreNeutrals leaves white, black and grey out of the main palette, so brand colors come first. textColors and backgroundColors still list them. A site that only uses neutrals gets them back with a note.

How to check which palette colors are readable together

Every row has contrastPairs: the best foreground/background pairs inside the palette with the WCAG contrast ratio and level (AAA, AA, AA-large, fail). Each palette color also has textOnIt (black or white, whichever reads better) plus contrastOnWhite and contrastOnBlack.

How to turn a palette into CSS or Tailwind

Leave includeSnippets on (default). Each row then holds cssVariables (:root { --color-1: #c23f10; ... }) and tailwindColors (colors: { 'palette-1': '#c23f10', ... }).

Input

FieldDefaultWhat it does
imageUrlssample photoDirect links to JPG, PNG, WebP, GIF, BMP or TIFF files.
websiteUrlsemptySites whose CSS colors you want.
colorsPerItem61 to 16 colors per item (images may return fewer if colors are similar).
methodkmeanskmeans or median-cut (images only).
ignoreWhite / ignoreBlackfalse / falseSkip near-white / near-black image pixels.
ignoreNeutralstrueWebsites: keep white, black and grey out of the main palette.
includeSnippetstrueAdd CSS variables and Tailwind colors to each row.
maxItems100Hard cap on images plus websites per run (max 5000).
maxImageMb15Larger images are skipped, free (max 25).
concurrency5Items processed in parallel.
timeoutSecs / retries30 / 3Per download.

At least one of imageUrls or websiteUrls is required.

Input example:

{
"imageUrls": ["https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg"],
"websiteUrls": ["https://www.python.org"],
"colorsPerItem": 6,
"method": "kmeans"
}

Output

From a real local run of the grapefruit image above (palette shortened to 2 of 6 colors, snippets shortened):

{
"source": "https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg",
"type": "image", "status": "ok", "error": null, "method": "kmeans",
"dominantHex": "#c23f10", "dominantName": "firebrick",
"palette": [
{"rank": 1, "hex": "#c23f10", "rgb": [194, 63, 16], "hsl": [16, 85, 41], "name": "firebrick", "percent": 44.9,
"textOnIt": "#ffffff", "contrastOnWhite": 5.23, "contrastOnBlack": 4.01},
{"rank": 2, "hex": "#d15b28", "rgb": [209, 91, 40], "hsl": [18, 68, 49], "name": "chocolate", "percent": 18.32,
"textOnIt": "#000000", "contrastOnWhite": 4.01, "contrastOnBlack": 5.24}
],
"hexList": ["#c23f10", "#d15b28"],
"contrastPairs": [{"foreground": "#9f2708", "background": "#e5cebb", "ratio": 5.01, "wcag": "AA"}],
"cssVariables": ":root { --color-1: #c23f10; ... }",
"tailwindColors": "colors: { 'palette-1': '#c23f10', ... }",
"width": 332, "height": 332
}

For https://www.python.org the same run found 623 color declarations over 3 stylesheets; the first palette entry was #ffd343 (gold, 46 declarations), then #3776ab, with themeColor #3673a5 and custom properties such as --color-default: #444444.

How much does it cost

Pay per event: $0.003 per palette extracted ($3.00 per 1,000). Only items that really produced a palette are charged. Failed downloads, blocked sites, non-image files, sites with no static colors, invalid URLs, duplicates and items over maxItems are free. There is no start fee. Platform compute usage is billed by Apify on top, small because each item is one download and a short CPU pass (not yet measured on Apify).

JobItemsCharge
A designer checks 20 logos20$0.06
A catalogue of product photos1,000$3.00
A competitor survey of sites plus images10,000$30.00
A large media library100,000$300.00

Use cases

  • Auto-tag a product catalogue or image library with its dominant color for filtering and search.
  • Pick a brand palette from a logo and check which pairs pass WCAG contrast.
  • Compare the CSS colors of competitor websites before a redesign.
  • Generate CSS variables or Tailwind colors from a mood-board image.
  • Pre-fill a placeholder background color for each image in a gallery or feed.

FAQ

Does it work on any website? Only on sites whose colors are in static HTML and CSS files. Sites that build styles with JavaScript return no-colors (free) or a partial palette. A site that blocks plain requests is reported as blocked; the Actor does not try to get around that.

Are website percentages the share of the screen? No. They are the share of color declarations in the CSS, so a color used in many small rules ranks above a large background used once.

Why do I get fewer colors than I asked for? Colors that are nearly identical are merged, and a flat image simply has few colors.

Are the results always the same? Yes for images: the algorithms have no random start. Websites can change between runs when the site changes.

Which images are accepted? JPG, PNG, WebP, GIF (first frame), BMP and TIFF under maxImageMb and 60 megapixels. SVG is rejected with an explanation.

Is it allowed to read any URL? Only public http(s) addresses. Private, local and cloud-metadata addresses are blocked, also after redirects. Use it on images and sites you may process.

Use with the Apify API / MCP / n8n / Make

Python:

from apify_client import ApifyClient
client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("<username>/color-palette-extractor").call(run_input={
"imageUrls": ["https://example.com/photo.jpg"], "websiteUrls": ["https://www.python.org"], "colorsPerItem": 6})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
print(row["source"], row["dominantHex"], row["hexList"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<APIFY_TOKEN>' });
const run = await client.actor('<username>/color-palette-extractor').call({
imageUrls: ['https://example.com/photo.jpg'], colorsPerItem: 6 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((r) => [r.source, r.dominantHex]));

The Actor works as a tool in MCP clients, and with the Apify nodes in n8n and Make: pass the input JSON above and read the dataset rows.

  • Company Logo & Favicon Finder: Download Logos from Any Website (find the logo, then extract its palette here)
  • Website Technology Checker: CMS, WordPress & Tracking Pixels
  • Image Compressor & Resizer: Compress Images in Bulk
  • Background Remover for Images (rembg, CPU)
  • Video Frame Extractor (extract frames from a video, then run the frame URLs through this Actor)