Files

13 KiB
Raw Permalink Blame History

ash-wallpaper.sh — guide

Turns a color photo into an Ash wallpaper: the image is reduced to Ash-tinted greys (dark variant), while warm ember/gold highlights (sunsets, fire, lamps, skin tones) are selectively kept — the "Pleasantville" effect.

Quick start

tools/ash-wallpaper.sh photo.jpg              # -> photo-ash.png
tools/ash-wallpaper.sh photo.jpg out.png      # custom output path

Be realistic about the defaults. This is a ~50-line ImageMagick script, not an AI — it applies one fixed rule (keep warm, high-saturation pixels; ash everything else) to your photo. The default settings are tuned for the classic cases (fire, sunsets, lamps). For anything else, expect to tune: the samples below were all post-processed in 23 iterations of HUE_MAX / SAT_MIN / SAT_MAX. A motif with little warm colour (e.g. a whale) simply has little to keep — no parameter will invent highlights that aren't in the source.

Requirements: ImageMagick 6.9+ or 7 (convert / magick). 4K input takes ~10s. All knobs are environment variables read once per run — tune one, rerun, compare.

How it works

  1. Hue band — the photo's HSL hue channel is thresholded: pixels with hue ≤ HUE_MAX or hue ≥ HUE_MIN form the "warm" band (reds, oranges, golds; the wrap-around at HUE_MIN catches pure crimson reds).
  2. Saturation gate — inside that band, a saturation ramp decides how much of the pixel survives: nothing below SAT_MIN, everything from SAT_MAX. This is what keeps dull, near-grey warmish pixels as ash.
  3. Softening — the combined mask is blurred, then re-sharpened with SENSITIVITY so highlights fade into the greys instead of showing hard cut-out edges.
  4. Base — a desaturated copy is tinted along the Ash dark ramp (BASE_LO shadows → BASE_HI highlights, default void → chalk).
  5. Composite — the original photo, with saturation multiplied by EMBER_BOOST, is laid over the base through the mask.

Parameters

Variable Default Meaning
HUE_MAX 13% Upper edge of the warm band, in percent of the hue circle (360°). 13% ≈ 47°, so reds, orange, ember and gold survive; yellows from ≈47° and all greens/blues fall out.
HUE_MIN 94% Lower edge of the wrap-around band (≥ 338°). Catches deep crimson/cherry reds whose hue sits just below 360°.
SAT_MIN 12% Saturation (HSL) below which a pixel becomes full grey, no matter its hue. Raise to make the image more monochrome (e.g. muted/desaturated photos: 1825%).
SAT_MAX 45% Saturation at which the highlight is fully kept. Pastel skies/candle-lit scenes peak below 45% — lower it (2535%) to let soft colour through; raise it (5570%) to keep only the most saturated embers.
SENSITIVITY 8x45% -sigmoidal-contrast applied to the mask: contrast x midpoint. Higher contrast → crisper, more cut-out-looking highlights; lower (e.g. 3x50%) → dreamier, feathered bleed. The midpoint shifts the whole mask: >50% = only the most certain warm pixels, <50% = more generous.
EMBER_BOOST 130 Saturation multiplier (%) on the surviving pixels, so the remaining embers read against all that ash. 100 = untouched colours, 160+ = intense glow. Applied to all channels of those pixels, so already-saturated fire can clip — reduce if it looks neon.
BASE_LO / BASE_HI #100f12 / #f3ede1 Endpoints of the grey ramp (void → chalk). Any colours work, e.g. BASE_LO=#1c1b1f BASE_HI=#e6dfd1 for a flatter panel→bone ramp.

Where the Ash palette sits in the hue wheel

For reference when widening/narrowing the band (hue in IM percent ≈ degrees/360):

Colour Hex Hue In band at defaults?
blood #c15c46 11° (3%)
rust #a86a48 21° (6%)
ember #e0914f 27° (8%)
gold #d6b46a 41° (11%)
pure yellow 60° (17%) (needs HUE_MAX=17%)
moss #8f9a5c 69° (19%)
steel #7c9aa1 187° (52%)
rot #b47e99 330° (92%) (needs HUE_MIN=88% — usually you don't want this)
violet #a585ac 292° (81%)

Samples

Freely-licensed photos from Wikimedia Commons, run through the script (900 px previews). Each entry lists the exact command; the originals are shown for comparison and credit.

Sunset over the sea

tools/ash-wallpaper.sh sunset.jpg
Original Ash
sunset original sunset ash

Source: “Leigh-on-Sea beach sunset (Unsplash)” by Joshua Fuller, CC0.

Campfire close-up

tools/ash-wallpaper.sh campfire.jpg
Original Ash
campfire original campfire ash

Source: “Closeup of raging flames in a large bonfire” by Nenad Stojkovic, CC BY 2.0.

Autumn foliage — warm-dominated scene

The whole park is bathed in warm orange, so ~90 % of the frame is "warm": like the fireworks case below, the result stays close to the original. Narrow the band (HUE_MAX=8%) to let only the saturated ember oranges through:

tools/ash-wallpaper.sh autumn.jpg
Original Ash
autumn original autumn ash

Source: “Münster, Park Sentmaring 2015 9923” by Dietmar Rabich, CC BY-SA 4.0.

City at night (ISS)

Street lamps glow soft yellow — the wide-band + soft-gate recipe from below:

HUE_MAX=17% SAT_MIN=8% SAT_MAX=60% SENSITIVITY=4x50% \
  tools/ash-wallpaper.sh city.jpg
Original Ash
city original city ash

Source: “Windy City of Lights (ISS070-E-105097)”, astronaut photograph, NASA/JSC Crew Earth Observations — public domain.

Redhead portrait

Only hair and lips keep their colour; skin stays close to bone:

SAT_MIN=18% EMBER_BOOST=150 tools/ash-wallpaper.sh portrait.jpg
Original Ash
portrait original portrait ash

Source: “Woman redhead natural portrait 1” by dusdin (Flickr), cropped by Gridge, CC BY 2.0.

Candle light

A dark frame with a warm source — the ideal case; the flame and its glow stay, everything else turns to ash:

EMBER_BOOST=120 tools/ash-wallpaper.sh candles.jpg
Original Ash
candles original candles ash

Source: “Alive” by Ranit Sanyal, CC BY 3.0.

Fairground at night

Neon rides: the white structure greys out, the warm cabin lighting and the red LED strips survive. Uses the night recipe:

HUE_MAX=17% SAT_MIN=8% SAT_MAX=60% SENSITIVITY=4x50% \
  tools/ash-wallpaper.sh kirmes.jpg
Original Ash
fairground original fairground ash

Source: “Nighttime ferris wheel gondolas … Pattaya fairground” by PattayaPatrol, CC BY-SA 4.0.

Rainy night in Moscow

Red neon and traffic-light reflections are all the colour left — the same night recipe as above:

HUE_MAX=17% SAT_MIN=8% SAT_MAX=60% SENSITIVITY=4x50% \
  tools/ash-wallpaper.sh rain.jpg
Original Ash
rain original rain ash

Source: “Late autumn rainy night in Moscow” by kishjar?, CC BY 4.0.

Humpback whale — the low-highlight case

A daylight scene with almost no warm colour: only 0.4 % of the frame sits in the warm band, so the result is (intentionally) almost fully grey. Nothing is broken — there is simply little for the script to keep:

tools/ash-wallpaper.sh whale.jpg
Original Ash
whale original whale ash

Source: “Humpback Breaching” by NOAA National Marine Sanctuaries — public domain.

Fireworks — the negative case

Here the whole sky is lit red by smoke, so 96 % of the pixels are "warm" and the mask covers everything: the image is barely greyscaled at all. When the warm colour is the background rather than an accent, the effect has nothing to work with. Pick a different shot, or narrow the band (HUE_MAX=8%) to keep only the brightest sparks:

tools/ash-wallpaper.sh fireworks.jpg
Original Ash
fireworks original fireworks ash

Source: “Anjuna Beach, Goa, New Year's Eve, Fireworks in the sky” by Vyacheslav Argenberg, CC BY 4.0.

How much of each frame survived

The share of pixels the warmth mask keeps (measured with the default gate; the night-recipe samples were run with a wider band). A quick way to read the samples above, and a useful sanity check when tuning your own photo:

Motif Warm-pixel share (default) Result
Humpback whale 0.4 % almost fully ash
Fairground 4.2 % ash with neon accents
City at night (ISS) 17.0 % ash with a glowing street grid
Rainy night Moscow 17.2 % ash with red neon
Sunset 19.6 % ash with a warm horizon
Campfire 40.6 % dark ash, glowing flames
Redhead portrait 47.1 % ash with warm hair/lips
Candle light 73.2 % dark ash with a glowing flame
Autumn foliage 90.0 % barely greyed — warm is the scene
Fireworks 96.4 % barely greyed — warm is the scene

Rule of thumb: below ~25 % the effect is pronounced; above ~70 % the script has little to grey out and you should narrow HUE_MAX or pick another frame.

Recipes

# Warm sunset landscape, keep the drama
tools/ash-wallpaper.sh sunset.jpg

# Night city: street lamps are soft yellow-orange, need a wider + softer gate
HUE_MAX=17% SAT_MIN=8% SAT_MAX=60% SENSITIVITY=4x50% tools/ash-wallpaper.sh city.jpg

# Portrait: only eyes/lips/warm skin glow, everything else ash
SAT_MIN=18% EMBER_BOOST=150 tools/ash-wallpaper.sh portrait.jpg

# Almost pure grey with faint traces of ember
SAT_MIN=20% SAT_MAX=70% EMBER_BOOST=100 tools/ash-wallpaper.sh photo.jpg

# Flatter, dimmer base ramp
BASE_LO=#1c1b1f BASE_HI=#e6dfd1 tools/ash-wallpaper.sh photo.jpg

Batch generation

for f in ~/Pictures/vacation/*.jpg; do
  tools/ash-wallpaper.sh "$f"
done

Using the results

Drop the generated files into the theme or user backgrounds folder — Omarchy cycles through them with Super+Ctrl+Space:

mkdir -p ~/.config/omarchy/backgrounds/ash-dark
cp photo-ash.png ~/.config/omarchy/backgrounds/ash-dark/

Troubleshooting

  • Highlights cut with hard edges → lower the SENSITIVITY contrast (first number), e.g. 4x45%.
  • A warm object disappears → its hue is outside the band (check the table above) or its saturation is below SAT_MIN.
  • Grey areas look slightly tinted/brown → those pixels are just inside the band; raise SAT_MIN.
  • Fire/embers look clipped and neon → lower EMBER_BOOST towards 100.
  • Image too bright/dark after tinting → adjust BASE_LO/BASE_HI instead of editing the photo.