Draw a big-headed politician in C#

[big-headed]

This example shows how you can draw a big-headed person such as a politician. Before I start, let me say I’m not trying to bash Donald Trump in particular here. Originally I was planning to make images for all of the presidential candidates with the sizes of their heads depending on their standings in the polls. With more than 20 candidates and the possibility of more on the way, however, I decided it would just be too much work. I encourage you to make images for the others if you like. (Particularly for tomorrow’s example, which would be really funny with 20 images!)

Anyway, Donald Trump currently seems to have the biggest head, so The Donald seemed like the natural place to start.

For this example, I needed an image with enough room over the person’s head to display the head at double scale. That kind of image is pretty hard to find because most photographs are cropped close to the top of the person’s head, so I found a picture with a plain background and edited it to create more headroom.

Next I separated the image into two copies holding the body and the head. I gave the head image a green background. The background should be any color that does not appear in the head’s image. The following picture shows the original image and the separated body and head images.


[big-headed]

The program holds the body and head images in hidden PictureBoxes named picBody and picHead.

When the program starts, it uses the following code to create the combined big-headed image.

private Bitmap BmHead, BmBody, BmCombined;
private PointF Chin, Origin;

private void Form1_Load(object sender, EventArgs e)
{
    // The body is scaled by 0.5 so the head looks big.
    const float BodyScale = 0.5f;

    // Make the body image.
    Bitmap bm_body = (Bitmap)picBody.Image;
    int body_wid = (int)(bm_body.Width * BodyScale);
    int body_hgt = (int)(bm_body.Height * BodyScale);
    BmBody = new Bitmap(body_wid, body_hgt);
    using (Graphics gr = Graphics.FromImage(BmBody))
    {
        Point[] dest_points =
        {
            new Point(0, 0),
            new Point(body_wid, 0),
            new Point(0, body_hgt),
        };
        gr.DrawImage(bm_body, dest_points);
    }

    // Make the head image.
    BmHead = (Bitmap)picHead.Image;
    // Use the upper left corner's color as the transparent color.
    Color transparent = BmHead.GetPixel(0, 0);
    BmHead.MakeTransparent(transparent);

    // The tip of chin is at (273, 383) in unscaled coordinates.
    Chin = new PointF(273 * BodyScale, 383 * BodyScale);

    // Origin is where we need to draw the upper left
    // corner of the head to place it on the tip of the chin.
    Origin = new PointF(
        Chin.X - BmHead.Width / 2,
        Chin.Y - BmHead.Height + 15);

    // Make the combined image.
    BmCombined = (Bitmap)BmBody.Clone();
    using (Graphics gr = Graphics.FromImage(BmCombined))
    {
        gr.DrawImage(BmHead, Origin);
    }
    picBigHead.Image = BmCombined;

    // Size the form to fit.
    ClientSize = new Size(
        picBigHead.Right + picBigHead.Left,
        picBigHead.Bottom + picBigHead.Top);
}

The program uses three Bitmap objects: BmHead, BmBody, and BmCombined.

The point ChinX represents the location where the tip of the head’s chin is on the scaled image.

The point Origin is the location where we need to draw the head to position its chin on the scaled body image. (We assume the tip of the chin is near the bottom middle of the head image.)

The constant BodyScale holds the amount by which the body image is scaled to make it smaller than the head. This example scales the body by a factor of 0.5 so the head appears twice as large as it should. (This is where you would use the politician’s poll number to get the scale.)

After defining BodyScale, the code makes a body image. It saves the picBody image in the Bitmap named bm_body. It scales the size of that image and creates the new Bitmap BmBody with the scaled size. It then copies the original body image into BmBody at the scaled size.

Next the code creates the head image. It saves the image in the picHead control in the Bitmap named BmHead. It then gets the color of the image’s upper left pixel and uses the Bitmap‘s MakeTransparent method to make all pixels of that color transparent in the Bitmap. (That’s why I set the head image’s background to green. That’s also why green must not appear in the head image. If it does, then there will be transparent holds in the image.)

The program then sets Chin to the location of the chin in scaled coordinates. (I got the position by simply using MS Paint.) It sets Origin to the location where we need to draw the head to align its chin with the Chin location.

Finally the program creates the Bitmap BmCombined by cloning the scaled body image. It then draws the unscaled head on top and displays the result. It finishes by sizing the form’s client area to fit the result PictureBox.


Download Example   Follow me on Twitter   RSS feed   Donate




About RodStephens

Rod Stephens is a software consultant and author who has written more than 30 books and 250 magazine articles covering C#, Visual Basic, Visual Basic for Applications, Delphi, and Java.

This entry was posted in algorithms, graphics, image processing and tagged , , , , , , , , , , , , , , . Bookmark the permalink.

One Response to Draw a big-headed politician in C#

  1. Pingback: Make a bobblehead in C# - C# HelperC# Helper

Leave a Reply

Your email address will not be published. Required fields are marked *