WordPress / WordPress/performance

Image Placeholders: average pixels in linear light to avoid gamma-skewed dominant color

Open
#2,535 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

[Plugin] Image Placeholders [Type] Enhancement no milestone
Dominant language
PHP
Stars
461
Forks
165
Avg merge
11h 12m
Merged PRs (30d)
28

Description

Feature Description

The Image Placeholders plugin (formerly Dominant Color Images) extracts the dominant color of an image by resizing it down to a single 1x1 pixel and reading that pixel's color. This is done in both the Imagick and GD editors:

A community member (@MarcinDudekDev) pointed out in this comment that both Imagick and GD average pixels in gamma-encoded sRGB space, which skews the resulting color darker and less saturated than what the eye actually perceives. This is the classic "gamma error in picture scaling" problem.

Quick illustration: a 50/50 black/white checkerboard averaged in gamma space gives #808080. Averaged in linear light (what you'd see squinting at the image from a distance) it's #BCBCBC - about 20 L* lighter. Real photos land at 4-9 L* off, worst on high contrast - skies with dark foregrounds, foliage, speculars.

Side-by-side demo with sample photos (you can drop in your own test images): https://marcindudekdev.github.io/img2gradient/gamma-demo.html

Proposed Fix

The fix is cheap for this use case (a single 1x1 average):

  • Imagick: transform to linear colorspace before the resize and back to sRGB after, i.e. the transformImageColorspace( Imagick::COLORSPACE_RGB )resize 1x1transformImageColorspace( Imagick::COLORSPACE_SRGB ) recipe.
  • GD: GD has no colorspace support, but since the current implementation can iterate pixels anyway, the fix is to decode each pixel through a 256-entry sRGB→linear LUT, average in linear light, then re-encode to sRGB. A few extra lines, negligible cost. (Note: this would replace the current imagecopyresampled() 1x1 downscale, which itself averages in gamma space.)
  • libvips (for reference): vipsthumbnail has a --linear flag for exactly this, off by default.

The reporter ran into this while building a gradient placeholder generator (MarcinDudekDev/img2gradient) and noted the linear-light fix was visibly better on photos immediately.

Considerations

  • The change would shift extracted placeholder colors lighter/more saturated, so existing stored dominant_color post meta would not match newly computed values. Regeneration would be needed for consistency, though placeholder colors are not critical so a gradual migration is fine.
  • Worth adding test coverage with a high-contrast fixture (e.g. a black/white checkerboard) where the gamma vs. linear difference is largest and easy to assert on.

Reported via community feedback from @MarcinDudekDev.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with class-dominant-color-image-editor-imagick.php at get_dominant_color() and class-dominant-color-image-editor-gd.php at get_dominant_color(), then inspect existing tests for both editors. Verify the 1x1 color is averaged in linear light for Imagick and GD, and add high-contrast checkerboard coverage showing the expected difference from gamma-space averaging.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
performance
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.