Skip to content

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

Description

@adamsilverstein

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    [Plugin] Image PlaceholdersIssues for the Image Placeholders plugin (formerly Dominant Color Images)[Type] EnhancementA suggestion for improvement of an existing featureno milestonePRs that do not have a defined milestone for release
    No fields configured for Enhancement.

    Projects

    Status
    Not Started/Backlog 📆

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions