madoo.color-palette/v1
Madoo color palette — The colors an image is made of, by share: hex, OKLCh, CSS name, dominant, accent and background roles, a readable text color (Color Palette).
| Reference | madoo.color-palette/v1 |
| Schema id | urn:madoo:schema:color-palette:v1 |
| Version | 1.0.0 |
| Served at | GET /api/v1/json-schemas/madoo.color-palette/v1 · MCP get_json_schema |
Where it appears
Section titled “Where it appears”- Produced by:
image/color_palette→palette
Fields
Section titled “Fields”| Field | Type | Required | Rules | Description |
|---|---|---|---|---|
schema |
"madoo.color-palette/v1" |
yes | ||
image |
object | yes | ||
image.width |
integer | yes | ≥ 1 | |
image.height |
integer | yes | ≥ 1 | |
image.analysed_pixels |
integer | yes | ≥ 1 | Pixels read: the whole image, or a sample of about one megapixel (nearest pixel, never averaged) for a larger one. |
image.transparent_proportion |
number | yes | ≥ 0; ≤ 1 | Share of the pixels read that are transparent (alpha under 128) and left out: the background of a cut-out. |
settings |
object | yes | ||
settings.count |
integer | yes | ≥ 1; ≤ 16 | |
settings.background |
one of "mark", "exclude", "keep" |
yes | ||
settings.min_proportion |
number | yes | ≥ 0; ≤ 0.5 | |
settings.merge_distance |
number | yes | ≥ 0; ≤ 0.3 | A color closer than this (OKLab) to a larger one is counted in it instead of taking a place; a vivid color is never counted in a grey. |
colors |
array of objects | yes | max items 16 | |
colors[].hex |
string | yes | pattern “^#[0-9A-F]{6}$” | |
colors[].rgb |
array of integer | yes | min items 3; max items 3 | |
colors[].oklch |
object | yes | ||
colors[].oklch.l |
number | yes | Lightness, 0 (black) to 1 (white). | |
colors[].oklch.c |
number | yes | Chroma: 0 for a grey, about 0.3 for the most vivid sRGB colors. | |
colors[].oklch.h |
number | yes | Hue in degrees, 0 to 360; 0 for a grey. | |
colors[].proportion |
number | yes | ≥ 0; ≤ 1 | |
colors[].name |
string | yes | The nearest CSS named color (gray, navy, wheat…), measured in OKLab. | |
colors[].roles |
array of one of "dominant", "accent", "background" |
yes | dominant: the largest color that is not the background. accent: the most chromatic color (chroma at least 0.05), possibly the dominant one; the palette always shows it. background: the color surrounding the subject on the image border, with the shades of its backdrop. | |
colors[].text_color |
one of "#000000", "#FFFFFF" |
yes | Black or white, whichever is more readable on this color (WCAG 2 contrast). | |
colors[].contrast |
number | yes | ≥ 1; ≤ 21 | WCAG 2 contrast ratio of text_color on this color; 4.5 is the usual minimum for body text. |
dominant |
string or null | yes | Hex of the dominant color; null when the image has no opaque pixel. | |
accent |
string or null | yes | Hex of the accent color; null in a neutral image (whites, greys, blacks). | |
background |
string or null | yes | Hex of the background found on the border, also when it is excluded from colors; null when none surrounds the subject (a cut-out, a split image) or background is keep. | |
other_proportion |
number | yes | ≥ 0; ≤ 1 |
The complete schema
Section titled “The complete schema”madoo.color-palette/v1 (JSON Schema)
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "urn:madoo:schema:color-palette:v1", "title": "Madoo color palette", "description": "The colors an image is made of (Color Palette, image/color_palette). Colors are sRGB, ordered by how much of the image they cover. proportion is a share of the pixels the palette describes: the opaque pixels (alpha at least 128), without the background when it is excluded. other_proportion is what the listed colors leave out (colors under min_proportion or beyond count). The same image always gives the same document.", "type": "object", "required": [ "schema", "image", "settings", "colors", "dominant", "accent", "background", "other_proportion" ], "properties": { "schema": { "const": "madoo.color-palette/v1" }, "image": { "type": "object", "required": [ "width", "height", "analysed_pixels", "transparent_proportion" ], "properties": { "width": { "type": "integer", "minimum": 1 }, "height": { "type": "integer", "minimum": 1 }, "analysed_pixels": { "type": "integer", "minimum": 1, "description": "Pixels read: the whole image, or a sample of about one megapixel (nearest pixel, never averaged) for a larger one." }, "transparent_proportion": { "type": "number", "minimum": 0, "maximum": 1, "description": "Share of the pixels read that are transparent (alpha under 128) and left out: the background of a cut-out." } } }, "settings": { "type": "object", "required": [ "count", "background", "min_proportion", "merge_distance" ], "properties": { "count": { "type": "integer", "minimum": 1, "maximum": 16 }, "background": { "enum": [ "mark", "exclude", "keep" ] }, "min_proportion": { "type": "number", "minimum": 0, "maximum": 0.5 }, "merge_distance": { "type": "number", "minimum": 0, "maximum": 0.3, "description": "A color closer than this (OKLab) to a larger one is counted in it instead of taking a place; a vivid color is never counted in a grey." } } }, "colors": { "type": "array", "maxItems": 16, "items": { "type": "object", "required": [ "hex", "rgb", "oklch", "proportion", "name", "roles", "text_color", "contrast" ], "properties": { "hex": { "type": "string", "pattern": "^#[0-9A-F]{6}$" }, "rgb": { "type": "array", "items": { "type": "integer", "minimum": 0, "maximum": 255 }, "minItems": 3, "maxItems": 3 }, "oklch": { "type": "object", "required": [ "l", "c", "h" ], "properties": { "l": { "type": "number", "description": "Lightness, 0 (black) to 1 (white)." }, "c": { "type": "number", "description": "Chroma: 0 for a grey, about 0.3 for the most vivid sRGB colors." }, "h": { "type": "number", "description": "Hue in degrees, 0 to 360; 0 for a grey." } } }, "proportion": { "type": "number", "minimum": 0, "maximum": 1 }, "name": { "type": "string", "description": "The nearest CSS named color (gray, navy, wheat…), measured in OKLab." }, "roles": { "type": "array", "items": { "enum": [ "dominant", "accent", "background" ] }, "description": "dominant: the largest color that is not the background. accent: the most chromatic color (chroma at least 0.05), possibly the dominant one; the palette always shows it. background: the color surrounding the subject on the image border, with the shades of its backdrop." }, "text_color": { "enum": [ "#000000", "#FFFFFF" ], "description": "Black or white, whichever is more readable on this color (WCAG 2 contrast)." }, "contrast": { "type": "number", "minimum": 1, "maximum": 21, "description": "WCAG 2 contrast ratio of text_color on this color; 4.5 is the usual minimum for body text." } } } }, "dominant": { "type": [ "string", "null" ], "description": "Hex of the dominant color; null when the image has no opaque pixel." }, "accent": { "type": [ "string", "null" ], "description": "Hex of the accent color; null in a neutral image (whites, greys, blacks)." }, "background": { "type": [ "string", "null" ], "description": "Hex of the background found on the border, also when it is excluded from colors; null when none surrounds the subject (a cut-out, a split image) or background is keep." }, "other_proportion": { "type": "number", "minimum": 0, "maximum": 1 } }, "examples": [ { "schema": "madoo.color-palette/v1", "image": { "width": 1600, "height": 1200, "analysed_pixels": 1047252, "transparent_proportion": 0 }, "settings": { "count": 6, "background": "mark", "min_proportion": 0.01, "merge_distance": 0.12 }, "colors": [ { "hex": "#F4F1EC", "rgb": [ 244, 241, 236 ], "oklch": { "l": 0.9591, "c": 0.0074, "h": 80.72 }, "proportion": 0.5821, "name": "whitesmoke", "roles": [ "background" ], "text_color": "#000000", "contrast": 18.64 }, { "hex": "#1F3A5F", "rgb": [ 31, 58, 95 ], "oklch": { "l": 0.3467, "c": 0.0731, "h": 256.69 }, "proportion": 0.2412, "name": "darkslategray", "roles": [ "dominant" ], "text_color": "#FFFFFF", "contrast": 11.48 }, { "hex": "#C8102E", "rgb": [ 200, 16, 46 ], "oklch": { "l": 0.5304, "c": 0.2074, "h": 22.32 }, "proportion": 0.0934, "name": "crimson", "roles": [ "accent" ], "text_color": "#FFFFFF", "contrast": 5.88 } ], "dominant": "#1F3A5F", "accent": "#C8102E", "background": "#F4F1EC", "other_proportion": 0.0833 } ]}