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.
// http://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.

Comments (7)

  1. Mihailik says:

    The point is that the support of transparency differs a lot among formats.

    BMP (which is the default Paint format) does not supports transparency at all.

    GIF supports one-color transparency you are primarily talking about.

    PNG supports smooth multi-level transparency, where each pixel may have different level of transparency. It’s usually called alpha-channel transparency.

    JPG does not support transparency at all.

    TIFF may support or not support, depending on some particular format options. But it would be safer to presume it does never support transparency.

  2. Mihailik says:

    By the way, myBitmap.Save(…) saves the image to PNG format.

    It is because PNG supports most of features, even by the cost of bigger size. That’s why VS refuses to edit it natively.

  3. Eric W says:

    Forget all the technical stuff.  I think I laughed at the image for a good 60 seconds straight:)

  4. oresama says:

    I suggest Paint.Net.

    http://www.getpaint.net/