Previously, I had applied an RGB Euclidean distance vector to the
alpha channel of a jpeg and ended up with better results than Bitmap's
MakeTransparent. There was, however, still a slight halo around the
opaque parts of the image and I promised to show you a way that you
might be able to improve upon that.
The plan to help get rid of the halo is to truncate the map at a
lower an upper threshold and rescale the values in between. In other
words, we know that there are lots of colors close to white that we
want to throw away, and there's only a few colors around blue that we
want to keep.
I chose to scale my thresholds to 8 bits instead of making the user
guess (or know) the range of possible values for the distance map.
Here's the code to truncate and rescale:
public static void SetThreshold(Bitmap bm, double[][] distanceMap, int limit1,
int limit2)
{
double maxDistance = GetMaxDistance(bm);
double lim1 = Scale255ToDouble(limit1, maxDistance);
double lim2 = Scale255ToDouble(limit2, maxDistance);
for (int x = 0; x < distanceMap.Length; x++)
{
for (int y = 0; y < distanceMap[x].Length; y++)
{
distanceMap[x][y] = ScaleDistanceToRange(distanceMap[x][y],
maxDistance, lim1, lim2);
}
}
}
private static double ScaleDistanceToRange(double val, double maxVal,
double lim1, double lim2)
{
if (val <= lim1) return 0;
if (val >= lim2) return maxVal;
return ((val - lim1) / (lim2 - lim1)) * maxVal;
}
And here's the results... (Again, this doesn't work fully in IE because it won't make PNGs transparent!)
Original:
Original with alpha channel:
This is about as good as you can expect, however, I haven't tried
with a wider array of colors. I have a feeling that with more colors,
it might be worth transforming the image to CSV and processing based on
one or more of those channels.