Setting transparency in an image

Just as Jackie Chan does his own stunts; I do my own image drawing. Some of my "art":

The astute observer probably noticed that all of my work is very primitive and done in MS Paint (yup, "%windir%\system32\mspaint.exe") . Paint is fast. It's easy. And my poor abilities would be an insult to any real painting program.

However, the one thing I really could use that Paint is missing is the ability to set transparency in images. For example, in the images above, I'd like the white background to be a transparent color.

 

Setting the transparent color:

Tim explains how to make transparent images with Paint.Net. You can also do this programmatically with the Bitmap.MakeTransparent method. I wrote a simple C# console app to wrap the call. It picks the color in the upper left corner as the transparent color, which I think is a reasonably good heuristic.

Here's an example invoking it. "c.bmp" is the original file; "c.t.bmp" is a copy with transparency.

C:\temp> \bin\MakeTransparent.exe c.bmp
Loading image from:C:\temp\c.bmp
Choosing background color based of pixel at (0,0). Color =Color [A=255, R=255, G=255, B=255]
Saving back to file: C:\temp\c.t.bmp

 

Here's the code. It depends on System.Drawing.dll:

 // Simple tool to mark a color on the bitmap transparent.
// https://blogs.msdn.com/jmstall
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.IO;

namespace MakeTransparent
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine(
@"Usage:
    MakeTransparent <filename>

Makes the background color in the image transparent. 
This assumes the pixel at 0,0 is the background color. 

This saves it as a new file appended with '.t', so that it doesn't erase 
the original filename.  For example 'c:\dir\a.bmp' becomes 'c:\dir\a.t.bmp'.
Callers can rename as needed.
");
                return;
            }

            string filename = args[0];
            filename = Path.GetFullPath(filename);
            Console.WriteLine("Loading image from:{0}", filename);

            Bitmap myBitmap = new Bitmap(filename);

            // Get the color of a background pixel.
            // Assume upper left corner is opaque.
            Color backColor = myBitmap.GetPixel(0, 0);

            Console.WriteLine("Choosing background color based of pixel at (0,0). Color ={0}", backColor.ToString());

            // Make backColor transparent for myBitmap. This is the heart of the program.
            myBitmap.MakeTransparent(backColor);

            // Change "c:\dir\thing.bmp" to "c:\dir\thing.t.bmp"
            string left = Path.ChangeExtension(filename, null);
            string ext = Path.GetExtension(filename); // includes period ".bmp"
                        
            string outFile = left + ".t" + ext;
            Console.WriteLine("Saving back to file: {0}", outFile);

            myBitmap.Save(outFile);
        }
    }
}

 

Random notes:

  1. This works nicely on Bitmaps; but not on JPGs and other bitmap types. That's because this changes a specific pixel color (eg, 255;255;255) to transparent. Other image formats may have compression techniques that use a range of pixel colors in the background instead of a single color.
  2. Visual Studio's Bitmap editor does not like transparent images. I find after I run MakeTransparent on an image, VS won't open the image in its own editor and instead launches MS Paint.

 

Being practical...

I realize practically, I really should just use a better painting program (like Paint.Net). But I am a developer, so nobody expects me to be able to draw; and it provides a nice excuse to write random little apps. It's also nice for hooking into batch processes such as making all images in a directory have a transparent background.