Skip to content

Over-bright white edges around white artwork when decoding 8-bit Gray+Alpha PNG on real device (SDWebImage 5.21.7, iOS 26.6.2) #3888

Open

Description

@Hext123

What happened?

On a real iPhone, an image loaded with SDWebImage shows a ~1–2 px over-bright white ring on the anti-aliased edge of white artwork. The ring looks like HDR "super white": it is brighter than the pure white pixels of the same image.

The exact same PNG file loaded with UIImage(contentsOfFile:) on the same device looks correct.

Only white artwork shows the ring. Black / dark artwork with the same PNG encoding and the same kind of semi-transparent edges does not show it.

Source images that trigger the bug

Both are 450×450, 8-bit PNG, Gray + Alpha (color type 4), Generic Gray Gamma 2.2 profile. The anti-aliased edge is made of semi-transparent white pixels (for example gray=255, alpha≈7).

Image Image

How it looks on a real device

Photos of the actual screen. The circle sticker shows a thin bright ring around its edge when loaded with SDWebImage.

Image Image Image

How to reproduce

  1. Take fragile_label.png above (host it on a URL, or save it locally).
  2. On a real iPhone (not Simulator), show it in a UIImageView on a light background (we used #F7F7F9), and decode it two ways:
// B — wrong rendering: bright white ring around the white circle edge
imageView.sd_setImage(with: url)

// A — correct rendering: the same file, without SDWebImage
imageView.image = UIImage(contentsOfFile: localPath)
  1. Compare the edge of the white circle:
    • With SDWebImage: the edge is brighter than the pure white content of the image.
    • With UIImage(contentsOfFile:): the edge looks normal.

A 204×204 downscaled version of the same artwork (same Gray+Alpha encoding) also reproduces the ring.

What we measured (informational only)

  • A screenshot of the wrong rendering contains a gain map. Measured in extended linear Display P3, the ring luminance is about 4.5× SDR white (page background ≈ 1.0). So the ring is really brighter than white — not a visual illusion.
  • Decoded-image properties (real-device log):
A (UIImage direct): 450x450 bpc=8 bpp=16 alphaInfo=.last (raw 3)             colorSpace=Generic Gray Gamma 2.2
B (SDWebImage):     450x450 bpc=8 bpp=16 alphaInfo=.premultipliedLast (raw 1) colorSpace=Generic Gray Gamma 2.2
  • We also compared the two decoded bitmaps pixel by pixel:
    • alpha channel: identical for every pixel
    • every semi-transparent edge pixel: byte values identical between A and B (none of them is brighter in B)
    • only fully-transparent pixels' color bytes differ (zeroed in B) — invisible either way

So the over-bright edge is not present in the decoded bytes themselves. At decode time, the visible difference between A and B is the CGImageAlphaInfo tag (straight vs premultiplied).

  • On the same device, all of these render correctly:

    • UIImage(contentsOfFile:) / UIImage(data:) directly
    • converting the PNG to 8-bit sRGB RGBA first, then the same SDWebImage code path
    • re-rendering the SDWebImage result with UIGraphicsImageRenderer (preferredRange = .standard, transparency kept)
    • Kingfisher 7.9.1 with default options
  • Our guess (may be wrong): the straight alpha flag is replaced with a premultiplied flag, so the semi-transparent white edge pixels get composited at full strength. We are not sure (informational only)

Environment

  • SDWebImage 5.21.7 (CocoaPods)
  • iPhone 13 Pro, iOS 26.6.2, real device
  • UIImageView + sd_setImage(with:), default options (.retryFailed)

Thank you!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions