Image that looks different on black background and on white
If you put this image on a black background you see something different than on a white background. Does anyone have a idea how it works?
I'm going to ignore the actual picture in your question, and just answer the question implied in the title: How to create a PNG image the looks different on a black background than on a white one?
Specifically, the method I'll describe will allow you to combine any two grayscale images A and B into one PNG file C, so that C looks like A on a black background and like B on a white background, with one condition: every pixel of A must be equal to or darker than the corresponding pixel of B. (If the original images don't quite satisfy that condition, the method I'll describe will force them to, leading to some "ghost image" leakage from one to the other. Depending on the images, this may or may not be visually apparent.)
The trick, of course, is to make use of the PNG alpha (= opacity) channel. Specifically, given a pixel with color c and opacity α, the pixel will have the apparent color a = αc on a black background and b = αc + (1−α) on a white background. (Here, color 0.0 represents black and 1.0 represents white.) Turning this around, given target pixel colors a and b, we can solve these equations for c and α:
- 1 − α = b − a
⇒ α = 1 − (b − a) = 1 − b + a, and
- c = a / α
(This, of course, assumes than a ≤ b; otherwise the transparency 1 − α would be negative, which the PNG format, alas, does not support.)
OK, so how can we do these calculations in a graphics editor like the GIMP or Photoshop? Well, we really just need two operations — subtraction and division — and, as it happens, GIMP (and, if I'm not completely mistaken, Photoshop too) has both of these implemented as layer composition modes.
In fact, the process is essentially the same as the one I described in this answer for reconstructing the alpha channel of an image from versions superimposed on black and white backgrounds; the only difference is that we start from two arbitrary images — for example, these two cat photos from Wikimedia Commons:
I've cropped these images, converted them to grayscale and adjusted their color levels so that they almost — but not quite, just to show what happens — satisfy the relative lightness condition a ≤ b. (Tip: the "lighten only" and/or "darken only" layer modes are handy for checking this.)
Now, I'll do the following steps:
- Open both images as layers of a single picture.
- Make a copy of the black cat layer, change its layer mode to "subtract" and merge it down into the white cat layer. The result will be the transparency of the final image.
- Make a copy of the transparency layer we just created, invert it, change its layer mode to "divide" and merge it down to the remaining copy of the black cat layer. This will be the luminance channel of the final image.
- Move the transparency layer to top and make it visible, and use the channels dialog to transfer it to the selection. Then select the luminance layer and cut the selection out of it. Finally, delete the transparency layer.
- Save the remaining layer as PNG. It should look like this:
This page has a white background, so you should see the white kitten image (but with some faint "ghosts" of the other image where the a ≤ b condition wasn't satisfied), but you can download the image above and confirm that it looks quite different on a black background. Or just compare these flattened versions on black, white and purple backgrounds respectively:
The last version shows what's going on: the purple areas are where the PNG above is transparent, allowing the background color to show through. Conversely, the black and white areas are where the PNG image is opaque, making the color independent of the background.