Leveraging legacy color-keyed graphics in modern transparency aware APIs...

I only have a couple of words to start this off, and it is, “DirectDraw vs Direct3D”.  DirectDraw is so easy to use and implement from within C# and the managed world while Direct3D was such a marshalling nightmare.  Of course this was a couple of years ago when Managed DirectX wasn't around.  This nightmare convinced the .NET Terrarium team (well, I did the graphics sublayer, so it convinced me) to simply TlbImp the existing VB Type Libraries.  I think a lot of folks kind of went this route, since it was easy, and the feature set was pretty much everything you needed.

2 years later, what in the heck do you do with all of those legacy color-keyed graphics?  Better yet, what if you find the perfect graphics on the web, but they are in a legacy format?  Conversion by hand is a possibility.  However, GDI+ seems to be quite overpowered in terms of image processing, and quite underpowered in terms of raw screen drawing.  Because of this you have a prime candidate for converting all of those graphics assets over quickly.  The .NET Terrarium made use of a Magenta color key for all transparency effects.  Magenta and Lime were and still are the colors of choice for transparency marking (though some shades of blue are becoming popular) in image file formats that don't support true transparency (or rather APIs that don't have support for transparency except through color keying, aka DirectDraw).  In GDI+ color keying, or rather color remapping, can be accomplished using a ColorMap structure.

ColorMap mapping = new ColorMap();
mapping.OldColor = ColorTranslator.FromHtml(transparentColor);
mapping.NewColor = Color.Transparent;

That is easy enough.  With just a couple of lines of code, we can use this color mapping to create a new art asset in another format (I suggest PNG since we are doing Alpha) to use with modern day APIs (aka Direct3D).  The full program with error checking stripped out is only a few lines of code and manages to take any arbitrary bitmapped graphic and convert a single color within the file to transparent.  If you need multiple color mapping conversions, you can always add that support to the code.

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

public class PNGTransparent {
    private static void Main(string[] args) {
        // Grab our arguments
        string inputFile = args[0];
        string outputFile = args[1];
        string transparentColor = args[2];
        
        // Create the images we'll be using
        Image inputImage = Image.FromFile(inputFile);
        Image outputImage = new Bitmap(inputImage.Width, inputImage.Height, PixelFormat.Format32bppArgb);
        
        ImageAttributes conversion = new ImageAttributes();
        GraphicsUnit boundsUnit = GraphicsUnit.Pixel;
       
        ColorMap mapping = new ColorMap();
        mapping.OldColor = ColorTranslator.FromHtml(transparentColor);
        mapping.NewColor = Color.FromArgb(0, 255, 0, 255);
        
        conversion.SetRemapTable(new ColorMap[] { mapping });
        
        using(Graphics gfxConversion = Graphics.FromImage(outputImage)) {
            gfxConversion.DrawImage(
                inputImage,
                new Rectangle(0, 0, outputImage.Width, outputImage.Height),
                0, 0, inputImage.Width, inputImage.Height,
                GraphicsUnit.Pixel,
                conversion
            );
            gfxConversion.Dispose();
        }
       
        outputImage.Save(outputFile, ImageFormat.Png);
    }
}

Published Monday, April 05, 2004 7:31 PM by Justin Rogers
Filed under: ,

Comments

No Comments

Leave a Comment

(required) 
(required) 
(optional)
(required)