Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Statamic Image Colors Laravel Package

4rn0/statamic-image-colors

A Statamic addon that extracts dominant colors from uploaded images, so you can build palettes for backgrounds, overlays, and theme accents directly in your templates. Lightweight, easy to configure, and handy for dynamic, image-driven design.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the addon with Composer, publish any config it ships, then run the extract command against an asset container (or select images in the asset browser and run the Extract colors action). The addon samples each image and writes its result to a single imagecolors key on the asset — there is no separate table or model to learn.

Look first at:

  1. The asset's imagecolors value in the CP or via $asset->get('imagecolors'). That one array is the whole data model: colors (the palette), stamp (a marker proving the addon wrote it), and color (the pinned choice, if an editor made one).
  2. The README's template examples — they are the canonical reference for the Antlers tags, and they're accurate as of this release (the previous text-over-image example was not).
  3. The asset container blueprint, only to confirm you have not already used imagecolors as a field handle.

First use case: give a hero image a palette, pin a color, and render it — {{ hero:imagecolors }} for the pinned/derived color, {{ hero:imagecolors:colors }} to loop the palette.

Implementation Patterns

Treat imagecolors as a reserved namespace, not a field you own. Read from it, and write to it only through the addon's action or command. Don't add your own imagecolors field to a blueprint or merge values into that array — see gotchas.

Color rendering. {{ hero:imagecolors }} prints the chosen color; {{ hero:imagecolors:color }} gives you the same color with per-format modifiers; loop {{ hero:imagecolors:colors }} for swatches, palette chips, or a gradient fallback. {{ hero:imagecolors:is_pinned }} is the signal that an editor deliberately picked a color — use it to decide whether to show a "pin color" affordance or to trust the value blindly.

Conditions must use properties, not methods. This is the pattern that actually works now:

{{ if hero:imagecolors:color:is_dark }}
  <div class="overlay overlay--dark">
{{ /if }}

{{ if hero:imagecolors:is_pinned }}…{{ /if }}

{{ if hero:imagecolors:color:contrast >= 4.5 }}…{{ /if }}

Readable text over images: use a band, not :contrast. Since :contrast measures against the solid extracted color, it tells you nothing about white text sitting on the photo. Put the title on a band filled with the image's color and test contrast against that:

<div class="hero" style="background-image:url('{{ hero:url }}')">
  <div class="hero__band" style="background: {{ hero:imagecolors }}">
    <h1>{{ title }}</h1>
  </div>
</div>

GraphQL. The ImageColors type exposes the same three fields (color, colors, isPinned-style equivalents). Request it directly on the asset; no separate query or resolver plumbing is needed. Remember to refresh the GraphQL schema cache after install.

Batch extraction. Run the action on a selection rather than per-asset. Handle the two failure shapes: a hard failure message when nothing could be read (treat as an error, surface it), and the informational "Colors extracted for 1 of 2 images" when only some succeeded (treat as a warning, log the rest). Pair this with the stamp value to re-extract only assets whose stamp is missing or stale.

Idempotency. Because results are keyed and stamped, re-running extraction is safe. Schedule it if editors upload in bulk, or hook asset save and dispatch extraction for images lacking a stamp.

Gotchas and Tips

  • Silent bail-out on key collision. If a blueprint already defines an imagecolors field, or an asset holds an imagecolors value the addon didn't write, the addon does nothing — no sampling, no swatches, no overwrite — and the only signal is a log line. If extraction "doesn't work" for exactly one container, grep the log for the image path before debugging anything else. Fix by renaming your field handle; the namespace is not configurable.
  • Breaking template changes. {{ hero:color }} and {{ hero:colors }} are gone. Grep your Antlers views for :color }}-adjacent patterns and any old imagecolors-less usage when upgrading. Any .blade.php or cached view using the old tags will render empty rather than error.
  • Conditions were silently false before this release. If your templates carry {{ if … }} blocks around is_dark, is_pinned, or contrast that "never seemed to fire," they're not your bug — and they may now start rendering for the first time. Re-check layouts that depended on those blocks never showing.
  • :contrast scope. It's relative to the solid color. Don't use it to validate text on a photo; the README's band approach is the correct pattern.
  • Action messaging changed. Anything that asserted on the old always-success phrasing ("Colors extracted") will now see failure and partial-success strings. If you parse output in CI, adjust.
  • Cache layers. Extractions land in asset data via the Stache; if fresh colors aren't visible in templates, check static caching / response caching and the GraphQL schema cache before assuming extraction failed. Confirm with $asset->get('imagecolors') in tinker.
  • Log is the only diagnostic surface. Every "kept out" case, unreadable image, and partial failure is reported there and nowhere else in the UI. Tail the log during the first production run.
  • Extension points are limited by design: the namespace is fixed and the fields are fixed. Customize at the presentation layer — derive swatch markup, gradients, and dark/light decisions from colors rather than trying to add fields into imagecolors.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package