Fernando Voltolini de Azambuja

Reflective display · color science · software

Rendering images with six e-paper colors

A measured-color approach to six-state rendering: lower computed color error across eight images, with tradeoffs in shading and texture.

Approximating an image with six pixel colors

This display gives each pixel six choices: black, white, red, yellow, green or blue. A photograph contains many more colors. The renderer must approximate them with neighboring pixels, using halftoning to distribute the available colors while retaining shading and detail.

I built a renderer guided by measurements of the six native colors, then compared it with Pimoroni's image-conversion software. The question was whether those measured references could bring the rendered color mixtures closer to the source image, and what that choice would do to tone and texture.

Hokusai's Great Wave, interpreted as sRGB and fitted to the display frame
Shared source · interpreted and fitted
Native pixel states chosen by the Pimoroni route for the same Great Wave source
Pimoroni route · six-state preview
Native pixel states chosen by the project renderer for the same Great Wave source
Project renderer · six-state preview

Software previews, not panel photographs. Both renderers receive the same interpreted, fitted source. The same visualization palette is applied to both pixel maps so their native-state choices can be compared. These previews show pixel choices; they do not predict the colors reflected by the panel.

Katsushika Hokusai, Under the Wave off Kanagawa (The Great Wave), ca. 1830–32. The Metropolitan Museum of Art, JP1847. Public domain. Only the frame's side padding is hidden here; the artwork is not cropped.

More image comparisons

Rendered previews share one six-color palette. Select an image to view it at full size.

Coffee

Source photograph of a coffee cup on a wooden table
Source
Coffee rendered with Pimoroni's six-color method
Pimoroni
Coffee rendered with my measured-color method
My renderer

Photograph: Rachel Michetti, courtesy of Pikolo Espresso Bar. scikit-image sample, CC0.

Chelsea

Source photograph of Chelsea, a tabby cat
Source
Chelsea rendered with Pimoroni's six-color method
Pimoroni
Chelsea rendered with my measured-color method
My renderer

Photograph: Stefan van der Walt. scikit-image sample, CC0.

Lower computed color error, with local losses

I compared both renderers on eight development images: four real images and four synthetic targets. Each received the same interpreted image and framing. I divided the image content into complete 16 × 16 pixel tiles, averaged each tile's source color in D50 XYZ, and compared it with the average color implied by its selected native states.

The calculation weights the six measured native colors by their pixel counts. CIEDE2000 (ΔE00) expresses the distance between that reference mixture and the source color; lower is closer. My renderer had a lower mean on every image. Giving each image equal weight produced the comparison below.

Computed mean reference color error across eight development images, ΔE00
Rendering routeMean reference error
Pimoroni renderer18.545
My renderer, Floyd–Steinberg11.134

I also checked individual regions because an image average can hide a poor shadow, edge or small colored feature. Some regions favored Pimoroni. On the coffee photograph, the 95th-percentile tile error rose from 19.405 for Pimoroni to 20.019 for my renderer, even though my renderer's image mean was lower. This percentile describes the high-error end of the tile population, with about 95% of tiles at or below it.

These are calculated reference errors, not measured screen errors. The calculation assumes that native colors mix in proportion to their pixel areas. The pattern measurements show why actual reflected colors can depart from that assumption. The images were used during development; the comparison does not establish performance on unseen images or improved physical display appearance.

Shading and uniform areas exposed further tradeoffs

A useful rendering must keep neighboring shadow tones distinguishable without adding unwanted bands to a uniform area. I tested rising gray steps and constant-gray fields to examine those two requirements separately, then placed the tones together to see how earlier pixel choices affected later regions.

I tried mapping nearby gray requests onto a more widely spaced set of target levels to help preserve tone order. Some isolated patch tests kept the intended order, but the tested connected bands still showed reversals or variation within an unchanged requested tone. Constant-gray fields also produced varying local reference averages. Better average color error therefore did not settle the shading problem.

I also asked whether a white or black area between two regions would stop earlier diffusion error affecting the next region. Controlled examples produced identical white or black output pixels while carrying different numerical errors forward, sometimes changing a later gray region. Here, history means error carried between pixels in the calculation. The panel's response to earlier display updates is a separate measured question.

How measured colors guide the pixel choices

Pimoroni chooses pixels using a nominal RGB palette. My renderer uses the measured native colors as its numerical references. Both use error diffusion: the difference left by choosing one available color is shared with later pixels, helping neighboring pixels represent colors that no single pixel can supply.

  1. Interpret the imageUse its color profile, or explicitly declared sRGB, and fit it to the display frame.
  2. Work in color coordinatesConvert the interpreted image to D50 XYZ so it can be compared with the measured references.
  3. Choose and arrange statesSelect a native color and distribute the remaining numerical error to neighboring pixels.
  4. Prepare the display imageSave the native pixel map and the packed file used to send it to the display.
Color conversion and error handling

The source profile is converted to sRGB before the default route converts RGB to XYZ under D50, a standard daylight reference. Selection uses distances in CIELAB, whose coordinates describe lightness and two chromatic components. No display ICC profile or learned spatial predictor is applied on this route.

For each pixel, the renderer adds incoming XYZ diffusion error to the original color. It projects that combined value into the convex hull of the six reference colors, the range of their additive mixtures. It then chooses the closest native reference in Lab and passes only projected-value-minus-selected-color error to later pixels. The part removed by projection is discarded. This limits the numerical error being carried; the hull is a reference model, not measured panel gamut.

The retained method uses serpentine Floyd–Steinberg diffusion, alternating scan direction between rows. The comparison also includes Jarvis–Judice–Ninke, which distributes error over more neighbors. Pimoroni uses Pillow's Floyd–Steinberg dithering in RGB code values with its saturation-0.5 setting, which blends the reference palette entries.

The shared preview palette makes native-state choices visible. It uses measured colors scaled to the display's white and is separate from the numerical reference table used in the renderer calculation.

The alternative error-handling route increased average error

Limiting a working color to the reference range discards part of the numerical request. I compared the current route with an alternative designed to preserve more of the remaining color error for later pixels. It changed both the initial color mapping and the error carried between pixels. The question was whether that combination would improve color accuracy without worsening shading or detail. The fixed comparison covered 114 software conditions using images, flat-color fields and tone patterns.

Computed mean reference error across the eight development images, ΔE00. Each row compares the complete routes with the same diffusion method.
Diffusion methodCurrent routeAlternative
Floyd–Steinberg (FS)11.13411.243
Jarvis–Judice–Ninke (JJN)11.11911.329

The mean increased with both diffusion methods. Some images improved, but a flat dark-gray field's reference error rose from 8.11 to 14.73 ΔE00, and several tone and detail checks worsened. I retained the original Floyd–Steinberg route. This compared the complete mapping-and-feedback alternative within each diffusion method; it did not isolate which change caused the regressions or establish the best diffusion method.

What changed in the feedback comparison

The alternative first mapped each original source color into the reference hull. After adding incoming error, it projected the working value for selection but transported the full working-value-minus-selected-color difference. The retained approach projects the original color plus incoming error and transports only projected-value-minus-selected-color error. Both comparisons use the same original source-color targets.

Testing whether the computed gains carry to the display

The calculation favors my renderer across the development images, but the display's response to pixel arrangement can change the outcome. Display measurements are needed to determine whether those pixel choices also reproduce source colors more closely.

Flat-color fields will first compare color accuracy without photographic detail. An optional check of all six native colors will compare current readings with the references used by the renderer. The planned image comparison then examines three selected regions through three routes: Pimoroni, my renderer, and a variant that maps the original source colors into the reference range before error diffusion.

Nine image frames are prepared for this comparison, each translated to bring the selected region under one fixed meter position. Two planned readings per frame give 18 image-region readings. Moving the image rather than the meter preserves the local pixel patterns and reduces repeated manual placement, but changes the surrounding crop and white fill. The readings will therefore describe those translated conditions; whole-image shading, detail, texture and preference require a separate visual assessment.