I'm working on a project with a Flash programmer friend, Jack. In one
of those seemingly innocuous discussions that inevitably start with the
phrase "Shouldn't you be able to...". and end up with me furiously
flipping through books or googling for algorithms.
Jack needs to be able to upload an image in any reasonable format
(gif, jpeg, tiff, png) and have it converted to a png. That's easy
enough, but then he needs to be able to supply an x,y coordinate and
have the color of that pixel be made transparent. Again, that's not so
difficult in and of itself, but to make it look GOOD, you need to make
sure that you grab not only that color, but a range of colors.
That's all well and good, but by the time someone is uploading an
image, it's most likely got some anti-aliasing between the color you
want to be transparent and the colors you want to keep. That will
certainly cause some artifacts that we want to try to avoid...
So here's my plan of attack:
1. Calcualte the Euclidean distance of each of the pixels from the
color to be made transparent. There are a number of good websites with
information about this. The formula is:
d = SQRT((R1 - R2)2 + (G1 - G2)2 + (B1 - B2)2)
This will effectively make a grayscale bitmap whose pixels are black
if the colors are exactly the same as the target color and get lighter
as they stray away.
2. The next step is similar to what you do when you tweak the
histogram of an image in Photoshop. Any pixel whose value is less than
a given threshold will be made completely transparent (alpha value of
0%). Any pixel whose value is greater than another number becomes fully
opaque (alpha 100%). In between, the values are weighted to a scale
from 0-100%
3. Producing a transparent PNG from there is a simple matter of
applying that grayscale image to the alpa channel of the original
image! Getting that image into Flash 7 is another matter. (But that's
another show)
What about Bitmap.MakeTransparent(Color c) I hear you say? I'll be
it works great on images you have full control over and started off as
bitmaps, but what about jpegs which need to be supplied by anyone and
their dog? Here's what MakeTransparent does to a jpeg: (NOTE: this
sample doesn't work with IE because it doesn't properly display alpha
channels for PNGs)
Original:
Original with MakeTransparent(Color.White):