Color Palette Extractor: Dominant Colors from Images & Websites
Pricing
from $2.40 / 1,000 palette extracteds
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Security
Limited permissionsShare
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 rankedpalette(hex, rgb, hsl, name, percent, readable text color, contrast on white/black),hexList, bestcontrastPairs. cssVariablesandtailwindColorsblocks you can paste into a stylesheet ortailwind.config.js.- Websites also return
themeColor,textColors,backgroundColorsandcustomProperties(CSS variables that hold a color). - Bad URLs never stop the run. Failed items are free and listed in the
FAILEDrecord with the reason.
How to get the dominant colors of an image from a URL
- Put direct image links in
imageUrls, for examplehttps://example.com/photo.jpg. - Choose
colorsPerItem(default 6) and themethod:kmeans(smoother, default) ormedian-cut(classic, favors distinct colors). - 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
- Put sites in
websiteUrls, for examplehttps://www.python.org(thehttps://is added if you leave it out). - The Actor fetches the page and up to 6 stylesheets once each, counts every color in
color,background,border,fill,strokeand shadow declarations (hex,rgb(),hsl()and named colors), and ranks them. - By default
ignoreNeutralsleaves white, black and grey out of the mainpalette, so brand colors come first.textColorsandbackgroundColorsstill 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
| Field | Default | What it does |
|---|---|---|
imageUrls | sample photo | Direct links to JPG, PNG, WebP, GIF, BMP or TIFF files. |
websiteUrls | empty | Sites whose CSS colors you want. |
colorsPerItem | 6 | 1 to 16 colors per item (images may return fewer if colors are similar). |
method | kmeans | kmeans or median-cut (images only). |
ignoreWhite / ignoreBlack | false / false | Skip near-white / near-black image pixels. |
ignoreNeutrals | true | Websites: keep white, black and grey out of the main palette. |
includeSnippets | true | Add CSS variables and Tailwind colors to each row. |
maxItems | 100 | Hard cap on images plus websites per run (max 5000). |
maxImageMb | 15 | Larger images are skipped, free (max 25). |
concurrency | 5 | Items processed in parallel. |
timeoutSecs / retries | 30 / 3 | Per 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).
| Job | Items | Charge |
|---|---|---|
| A designer checks 20 logos | 20 | $0.06 |
| A catalogue of product photos | 1,000 | $3.00 |
| A competitor survey of sites plus images | 10,000 | $30.00 |
| A large media library | 100,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 ApifyClientclient = 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.
Related tools
- 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)