Custom Shaped Windows Forms From Images

One of the neat things you can do to make an application unique is give it a custom shape, and it’s surprisingly easy to do with windows forms. This article is going to show you how to make a ninja-shaped form in four ridiculously easy steps.

1. Find your image

This step is so simple, it’s almost not worth mentioning. You just need to find or create an image with the shape that you want. For the purposes of this article, I’m going to use this awesome ninja picture.

2. Edit the image

The next step is to edit your image by making undesired sections transparent. You can use Photoshop, Gimp, or any number of other editors to accomplish this. Here’s my transparent ninja image.

I added this image to my project and set its Copy to Output Directory property to Always so that it will be available in step 4. You could definitely compile it as a resource or handle this in a number of different ways if you didn’t want to deploy the image, though.

3. Create a region from your image

The third step is where you’ll actually have to do a little coding. The function below will scan through a provided bitmap pixel by pixel to create a region. (The original function comes from here. I made a slight adjustment to look for transparent pixels instead of a color provided as a parameter.)

private Region GetRegion(Bitmap _img)
{
    var rgn = new Region();
    rgn.MakeEmpty();
    var rc = new Rectangle(0, 0, 0, 0);
    bool inimage = false;
    for (int y = 0; y < _img.Height; y++)
    {
        for (int x = 0; x < _img.Width; x++)
        {
            if (!inimage)
            {
                // if pixel is not transparent
                if (_img.GetPixel(x, y).A != 0)
                {
                    inimage = true;
                    rc.X = x;
                    rc.Y = y;
                    rc.Height = 1;
                }
            }
            else
            {
                // if pixel is transparent
                if (_img.GetPixel(x, y).A == 0)
                {
                    inimage = false;
                    rc.Width = x - rc.X;
                    rgn.Union(rc);
                }
            }
        }
        if (inimage)
        {
            inimage = false;
            rc.Width = _img.Width - rc.X;
            rgn.Union(rc);
        }
    }
    return rgn;
}

4. Change the form’s region

That wasn’t so bad, was it? Now you’re basically done. The final step is simply to assign your newly created region to your form’s Region property.

private void Form1_Load(object sender, EventArgs e)
{
    var bitmap = new Bitmap("ninja.png");
    Region = GetRegion(bitmap);
}

Voila! You’re done, and now you have a sweet ninja form! (For added authenticity, modify the form’s opacity.)

Bonus material!

One of the problems with a custom shaped form is that you lose the title bar, so you can’t easily move it around. This can be remedied by adding some handlers to a few mouse events on the form, like so:

private bool _mouseDown;
private Point _startPoint;

private void Form1_MouseDown(object sender, MouseEventArgs e)
{
    _mouseDown = true;
    _startPoint = new Point(e.X, e.Y);
}

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
    _mouseDown = false;
}

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    if (_mouseDown)
    {
        var p1 = new Point(e.X, e.Y);
        var p2 = PointToScreen(p1);
        var p3 = new Point(p2.X - _startPoint.X,
                             p2.Y - _startPoint.Y);
        Location = p3;
    }
}

With this code in place, you can click anywhere in the form to move it around.

Advertisements

4 thoughts on “Custom Shaped Windows Forms From Images”

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s