views:

101

answers:

1

I'm dynamically mapping colours in an image that has alpha transparency in it to another (smaller set) of colours.

I've got code like:

var mappings = new List<ColorMap>();
foreach(var color in mapcolours)
{
    // Add mappings for all alpha values of the mask colour
    for(int i = 0; i < 256; i++)
    {
        var cm = new ColorMap();
        cm.OldColor = Color.FromArgb(i, mapcolour);
        cm.NewColor = Color.FromArgb(i, GetDestinationColour(mapcolour));
        mappings.Add(cm);
    }
}

var ia = new ImageAttributes();
ia.SetRemapTable(mappings.ToArray(), ColorAdjustType.Bitmap);
g.DrawImage(image_mask, destrect, 0, 0, image_mask.Width, image_mask.Height, GraphicsUnit.Pixel, ia);

But unfortunately (and I think its because I'm mapping all 255 alpha values of each colour) this eats up a LOT of CPU which has shown up during some profiling.

Is there a more efficient way to accomplish this? I can't stop mapping all 255 alpha values as otherwise the result looks terrible.

A: 

You should accquire a pointer to the raw image data with Bitmap.LockBits. Then you just loop over each pixel and look up it's color in a Dictionary. It will be super-fast.

danbystrom
Not sure that will be faster than gdi mapping. Need to be tested.
arbiter