Designing Color Scope
A photograph holds more than one story. Color Scope began as a different way to browse photographs. Instead of starting with a filename, a visitor could start with a color. Building that interaction exposed a more interesting question: which colors actually matter in a photograph?
A small red flower against a large blue sky became the test. So did a photographer who wanted to explore a collection by camera and film stock. Those two examples shaped the plugin: measured color, room for editorial judgment, and filters that belong to the collection rather than to a fixed category.
01 Measurements 02 Color picker 03 Matching 04 Subject focus 05 Flexible filters 06 Visual evolution 07 Editor and viewer 08 The finishing work 01 / Start with the photograph Keep a distribution, not one average color. A single average can describe a color that barely appears in the image. A single dominant swatch can lose the small detail that makes the photograph interesting. The early coarse bins needed to become a richer description of the actual pixels.
The plugin makes a small analysis copy, preserving the full composition and aspect ratio. Its longest side is bounded at 96 pixels. Nearby RGB samples are grouped, but each group keeps a real sampled pixel close to its mean as its representative. That distinction matters: the palette should show colors that came from the photograph.
Each image retains up to 256 measured color groups, two kinds of weight, and a spatial summary. Coverage describes how much of the image a color occupies. Attention adds an estimate of visual importance. The spatial summary keeps enough information to revisit a selected subject area without resampling the full photograph.
Every photograph contributes the same total weight to the collection display. A larger upload doesn’t get a louder voice simply because it contains more pixels.
The measurement path
Full compositionA bounded, uncropped analysis copy. Measured color groupsReal RGB representatives, coverage, and attention. Spatial memoryUp to 16 × 16 cells preserve color and position. Two outputsA collection-wide instrument and image-specific matching. The originals remain untouched. Compact profiles do the filtering work.
A note on color profiles and palette swatches The WordPress analyzer uses an embedded sRGB profile with Imagick when an input profile is available, with a separate GD fallback. Browser-added images in this playground use the browser’s image decoder and Canvas. Those are different processing environments. The image viewer groups measured colors in Oklab, merges near-duplicates, and selects up to three influential representatives. An almost monochrome image can have fewer than three; it doesn’t need invented colors to fill the space.
02 / Build a usable color instrument The coordinates stay fixed. The collection gives them shape. The displays borrow from photographic scopes, but the interaction is explicitly a hue-and-saturation map. It isn’t a broadcast Cb/Cr vectorscope. Keeping that distinction clear let the visual character serve a precise, understandable control.
Density scope Angle selects hue. Distance from the center selects saturation. Measured samples accumulate into clusters.Hue landscape Hue runs left to right. Peaks show prevalence. Vertical pointer position still chooses saturation.Radial spectrum Hue has a fixed direction. Bar length shows its weight. Pointer radius controls saturation.Color field Hue runs horizontally, saturation vertically. Contour bands reveal where measured colors concentrate.A pointer position is converted into a hue from 0 to 359 degrees and a saturation from neutral to fully saturated. Circular displays use angle and distance from the center. Rectangular displays use horizontal and vertical position. All four views feed the same matcher.
Pointer capture keeps a drag connected even when a finger or mouse moves outside the canvas. Fine controls provide separate hue and saturation sliders for keyboard use and precise adjustment. Quick swatches provide another way in.
The field represents the current collection, including its metadata filters and text search. It stays still while someone changes the color, sorts results, or moves between pages. Otherwise, selecting a color would erase the surrounding colors and move the target underneath the pointer.
The RGB and HEX readout belongs to the selected search color. The picker uses a normalized brightness for that reference. The viewer’s palette swatches are a different thing: measured colors from the actual photograph, including their lightness.
03 / Give the match range a clear meaning A wider search should still know what red means. The earlier wide-range behavior loosened two things at once: color similarity and the amount of matching color an image needed. At larger settings, the results could feel arbitrary. A predominantly red image shouldn’t become a green match just because the range is wide.
I separated tolerance from presence. The range now broadens a bounded neighborhood of related hues and saturation levels. It doesn’t lower the minimum presence rule. A candidate still needs enough matching color, a sufficient score, and a meaningful share of its chromatic palette.
Hue comparison uses both HSV hue and perceptual Oklab hue. That helps with natural olive and green neighbors that can be awkwardly spaced in HSV. Neutrals follow their own rule, instead of borrowing an arbitrary hue from almost gray pixels.
What the range changes
Precise12° neighborhood Related45° neighborhood
Hue tolerance expands with the slider. The required presence of matching color stays in place.
A wider setting explores neighboring colors. It does not turn the entire color wheel into a match.
The rules behind the result Hue tolerance is 12 + 33 × range, with range normalized from 0 to 1. Saturation tolerance expands from 0.22 to 0.85. Chromatic matches require at least 16% matching weight, a score of at least 0.105, and a share of the chromatic palette appropriate to the matching mode. Neutral matching requires 40% neutral weight. These are product rules, not a universal definition of photographic meaning.
The development checks included opposite hue families, natural olive foliage, small contrasting subjects, incidental color, and increasing range. A permissive range still had to reject unrelated primary colors. Changing a label on the slider wouldn’t have fixed the underlying behavior.
04 / The subject-focus dilemma The sky takes more space. The flower may matter more. The original question was specific: if a red flower occupies a small part of a blue-sky photograph, should the image be considered red? Coverage answers what occupies the frame. It can’t decide what the photographer meant.
In this example, automatic attention improves the red weight but still misses the eligibility rule. The selected subject area produces a match. That is exactly why the manual correction belongs in the editor.
05 / Make the filters belong to the collection A label is a choice. A value makes it useful. The first use case was camera and film stock. One photographer needed “Camera used for this shot” paired with “Nikon F3,” then “Film stock used for this shot” paired with “Kodak Portra 400.” Hard-coding Camera and Film would have solved only that one use case.
The editor instead gives each gallery three optional detail fields. The label belongs to the gallery. The value belongs to the individual image. A field-level switch decides whether the values also become a filter. Filled details still appear in the image viewer when filtering is off, while empty details disappear.
That same structure can describe an artist, material, location, client, project, season, or collection. It is open to the owner’s categories within three reusable fields, rather than promising a separate feature for every possible archive.
Previously entered values become suggestions. Bulk editing applies shared details to several images, while leaving unchecked fields alone. A recorded camera can be suggested when that metadata is available. Labels and switches don’t have to be re-entered for every photograph.
Same structure, different collections
Example collection Film photography Materials library Project archive
Labels are shared. Values are image-specific. Each field can become a filter.
From the 1.4.0 development build: the subject area and reusable label/value fields share the image-details editor. The pictured artwork is test imagery. Within one field Nikon F3 or another camera Several selected values are alternatives.
Across fields Camera and film and color Each additional field narrows the results.
Filtering changes which images are included and updates the count. Sorting changes their order. The scope then represents the metadata-filtered collection, so it can tell the color story of one camera, one material, or one project. Selecting a color narrows the photographs without rebuilding that base map.
Small rules that keep flexible fields manageable Values are compared without surrounding whitespace or letter-case differences. Filter choices come from values actually present in the gallery. Counts reflect the other active conditions, and unavailable options can be disabled without hiding a current selection. Search includes image details as well as titles and captions. A color reset leaves the metadata selection intact; clearing collection filters is a separate action.
These are categorical filters. Three reusable fields do not mean an unlimited field builder, date-range queries, or numeric comparison rules. The flexibility comes from letting each owner define useful categories without changing the plugin’s code.
06 / Finding the visual character From soft patches to weighted contours. The visual iterations were about making the data legible. The earlier fields were too muted. The right idea was there, but pale spots didn’t communicate the concentrated areas clearly enough.
An early comparison from the build: stronger cores improved the field, but the density still needed a clearer visual structure. The field places each weighted color at fixed hue and saturation coordinates, then spreads its influence through a Gaussian density calculation. Overlapping contributions build concentration. Contour bands make those differences visible without drawing every individual sample.
Hue wraps around the edge of the map, so red doesn’t become two unrelated regions at opposite ends. The bandwidth stays fixed. This keeps the relative color contributions meaningful while the collection determines the shape.
Once the contour structure worked, it still looked too transparent on white and too dim on black. The 1.5.3 refinement raised the six bands to 68%, 78%, 87%, 94%, 98%, and 100% opacity. The density map, coordinates, and underlying weights stayed the same.
Light and dark backgrounds are remembered independently for each display. The goal was a clear instrument in either setting, without muting the photographs to make the interface feel restrained.
Actual renderer comparison from the 1.5.3 update. Identical illustrative profiles, unchanged positions and weights, stronger separation from both backgrounds. 07 / Design both sides of the gallery The editor should explain what each choice changes. The editor developed alongside the front end. Six sections separate the starting design, images, layout and loading, color filter, image viewer, and style. Visual presets make the first choice concrete. A live preview connects every adjustment to its result.
The less common settings sit behind specific disclosures rather than filling the screen at once. Image details live with the images. Shared labels, bulk values, and subject focus use the same editing context because they all describe how a photograph participates in the gallery.
On smaller screens, the editor gives settings and preview their own space. The Save action stays reachable, inputs have room for readable text, and the image-detail dialog uses the available height. Reordering also has explicit arrows, so dragging is optional.
The image viewer has independent choices
Layout Simple / Image and story Tone Light / Dark Surface Solid / Blurred page The controls remember their values when the popup is disabled. Re-enabling it restores the chosen combination.
The viewer originally tied too many choices together. Separating layout, tone, and surface made eight combinations possible without eight unrelated presets. Navigation moved above the photograph. Notes became a content-sized panel that could be shown or hidden. The three influential colors stayed stacked vertically, with separate RGB and HEX copy actions.
Even the blur needed a structural correction. A compositing boundary in the viewer prevented a child background from sampling the page behind it. Moving the backdrop treatment to the outer viewer made the blur work without applying any filter to the photograph itself.
08 / Make repeated use feel settled The small shifts were worth investigating. Filtering to zero results exposed a sideways jump. It was measurable: the desktop scrollbar disappeared, adding 15 pixels to the viewport and moving the centered scope 7.5 pixels. Reserving that space and stabilizing short result sets addressed the cause.
Rapid selections also needed a different rhythm from a single change. The control and readout respond immediately. Incoming thumbnails get a short opportunity to prepare. Retained photographs ease into new positions, outgoing images leave once, and newer selections replace work that has become stale.
Horizontal galleries needed to retain the position after a drag. Arrow navigation now aligns to actual image boundaries rather than assuming every card has the same width. A movement threshold separates a deliberate drag from opening a photograph.
Input hints follow the way someone is interacting. Touch, mouse, and keyboard get appropriate guidance. Native page scrolling remains available outside the color control and subject-selection area. Reduced-motion preferences remove nonessential movement.
The WordPress version also separates cached page markup from the current public gallery manifest. Saving a gallery publishes its current settings and images; the renderer revalidates them instead of trusting an old cached embed. The public manifest keeps internal editing data out of its response.
Here, visitors have their own saved browser gallery. They can change settings, add images, adjust subject focus, rename detail fields, enable filters, and save the result back to the working gallery on this page. The editor and front end use the same renderer and matching logic.
Where it landed
Measured color. Human judgment. A collection’s own language. The result is a gallery that can be explored visually and configured around the material it contains. Its most important decisions are connected: a stable color map, bounded matching, a way to correct subject importance, and reusable fields that make the same system useful beyond its first photography example.
Development notes and limits The source package includes checks for color-family rejection, selected subject geometry, detail-field persistence, filter combinations, gallery layouts, caching behavior, and viewer settings. Those records distinguish real browser and WordPress checks from simulated DOM checks. They aren’t a claim that every device or hosting configuration behaves identically.
Automatic subject awareness remains an estimate. Small analysis copies and spatial summaries trade fine detail for fast, bounded work. The public editor saves to this browser, while the installable WordPress plugin saves authorized changes to the site’s gallery. Neither makes an artistic decision on the photographer’s behalf.