Notification Icon Fix
中文
A module for AOSP, MIUI and HyperOS. Using an algorithm to convert white notification icons into recognizable icons.
Supported System
- Android 8.1 ~ AOSP main branch
- HyperOS
- MIUI 10 and above
Screenshots
Algorithm Details
- Determine and reduce oversized icons exceeding the maximum allowed size (512×512 dp)
- (For MIUI) Detect transparent borders and symmetrically trim icons around the visual center
- (For MIUI and HyperOS) Determine if the icon has a marketing banner and replace it with a perfect icon (need to install it yourself)
- (For HyperOS) Determine if the icon is a weather icon and replace it with a real-time temperature icon (there is a system bug on HyperOS that causes this to malfunction)
- Build a full-image luminance histogram, compute the global Otsu threshold, and count the ratio of light vs. dark opaque pixels
- Collect border pixels from the outermost edge ring, and extract the dominant border color using K-means quantization
- Calculate the Euclidean distance in Lab color space between each border pixel and the dominant border color to determine whether the icon has a solid single-color border
- Sample several points along each of the four sides to compute an alpha-weighted representative color per side (skipping border-colored pixels); detect marketing-banner-style edge splits via a “three-sides-similar, one-outlier” rule with three tiers (strict, relaxed, weak); additionally detect corner badges where one corner color clearly differs from the other three
- If a marketing-banner edge split, corner badge, or low-resolution icon is detected, attempt to substitute the icon by extracting the launcher icon from the application
- Use CelebiQuantizer (Android 12+) or VariationalKMeansQuantizer to perform K-means quantization and extract the primary theme color of the icon
- Apply a circular mask to the icon, unconditionally clearing all pixels outside the inscribed circle to eliminate rounded-corner border regions
- Estimate a per-pixel background color by bilinear interpolation of the four side representative colors; separate foreground from background using a dynamically computed squared-distance threshold; fall back to Otsu luminance thresholding if the foreground pixel count degenerates (too few or too many)
- Convert foreground pixels to grayscale; if the foreground coverage exceeds 42% of opaque pixels, apply a second Otsu minority-clear pass to remove whichever of the dark or light side is the minority (skipped for gradient-like foregrounds)
- Tightly crop transparent edges from the final grayscale foreground pixels and output the minimal bounding rectangle with symmetric padding around the visual center
- Cache the result (icon and primary color) keyed by generation ID in a ConcurrentHashMap backed by SoftReferences for memory-efficient reuse