Background
I have a bunch of RGBA images. Imagine icons, logos or similar images that I would like to display. These images can be of any color. Please also note that the images are RGBA, so they have the fourth alpha channel for transparency.
Complication
Initially, I showed the images all on a white background. However, sometimes the whole image or parts of it were white, so these areas looked empty to the user.
The problem is that images are not all-white or all-black. There may be multiple colors and color gradients. And, due to the way RGBA images work, pixels are not always all one color and all opaque. Even if an image just showed a pure black icon in the center, there may be transition areas at the edges of the black icon with pixels of some transparency or more greyish colors.
Question
Assume, for each image I can choose between a black, grey, or white background. How can I algorithmically determine which of the three background color options is the best for any individual RGBA image?
By "best" I mean that no areas of the image should falsely appear empty and the highest contrast between image and background is achieved.
Example
In the toy example below, the icon I want to show has a white circle around it. So I cannot use white as a background color. I need to choose grey or black. Black would be best since it maximises contrast.
In the second toy example things are slightly more complicated since multiple areas of different color directly touch the transparent areas of the image. The black background appears to have the highest contrast but it is no longer trivial.
Ideas
- The inner parts of opaque areas do not matter. The background color would not affect the visibility.
- The inner parts of the fully transparent areas do not matter. There is nothing that could be made invisible.
- I would probably need to find those pixels in these transition areas between opaque and transparent. And then determine the color of these.
This appears awfully inefficient. Since most icons, logos, etc. have been designed for either a bright or a dark background, maybe it is sufficient to sample just a few pixels in the transition area between opaque and transparent?
I feel I am reinventing the wheel and someone must have found a solution to this problem before.
Existing questions on Stackoverflow
- I found existing questions on determining the best font color given a background color. However my problem is different. The problems I saw were only dealing with maximising the contrast between only two simple RGB colors.
Additional example 3
Note how this logo has a fine white line around it. This implies the optimal background color should probably be black.
Examples to play around with
Here are a dozen or so RGBA images to play around with. I don't own the copyright -- this is just for the illustration of the problem. Google Drive link
Edited in by Mark Setchell
I have added all sample images, going left-to-right as follows:
- over a chessboard to show transparent areas
- over black background
- over grey background
- over white background
- with just the alpha channel extracted