Understand fill modes in C#

[example]

C# drawing routines have two fill modes. In Windows Forms they are called Alternate and Winding. In WPF they are called Odd/Even and Non-Zero.

This example lets you draw polygons and see how the two fill modes determine which points are colored when you fill the polygon.

Fill Modes

In both modes, you can determine whether a point should be considered as inside the polygon by drawing a ray starting at the point and extending infinitely in any direction.

With the Alternate fill mode, the point is considered inside the polygon if ray crosses an odd number of the polygon’s edges.

[example]

For example, consider the red point in picture on the right. The black ray extending to the right crosses three of the polygon’s edges so that point is considered part of the polygon and it is shaded. In contrast, the ray extending from the green point crosses two edges so it is not part of the polygon.

With the Winding fill mode, you consider a ray leaving the point as before. This time you add one for each clockwise intersection and you subtract one for each counterclockwise intersection. Or if you prefer, add one each time the edge crosses the ray from left to right and subtract one when the edge crosses the ray from right to left.

[example]

For example, consider the rays shown in the picture on the right. From the red point, the ray crosses three edges right-to-left (-1), left-to-right (+1), and left-to-right (+1). The final count is +1, so the red point lies inside the polygon.

Next consider the green point. It ray crosses two edges left-to-right (+1) and left-to-right (+1). The final count is +2, so the green point also lies inside the polygon.

Finally consider the purple point. It ray crosses four edges right-to-left (-1), left-to-right (+1), right-to-left (-1), and left-to-right (+1). The final count is 0, so the purple point lies outside the polygon.

Note that the edges are considered clockwise/counterclockwise or left/right-to-right/left depending on the order in which the edges are drawn. Because the Winding fill mode relies on the total count being zero, it doesn’t matter which order you use. If the total is zero using one direction, then it will also be zero using the other direction.

A Surprising Case

[example]

It seems like the winding mode should fill “the whole polygon,” but it does not always as shown in the picture on the right. You can follow rays from a few points inside the isolated areas within the polygon to verify that this is correct.

The Example Program

The following snippet shows how the example program stores the points that make up the polygon.

private List Points = new List<Point>();
private bool Drawing = false;

The Points list holds the points. The Drawing variable indicates whether the user is currently defining a new polygon.

The following MouseClick event handler lets the user add new points to the list.

private void picCanvas_MouseClick(object sender, MouseEventArgs e)
{
    // See if this is a left or right click.
    if (e.Button == MouseButtons.Left)
    {
        // Left click.
        if (!Drawing)
        {
            // Start a new polygon.
            Points = new List<Point>();
            Drawing = true;
        }

        // Add the point to the polygon.
        Points.Add(e.Location);
    }
    else
    {
        // Right click.
        Drawing = false;
    }

    // Redraw.
    picCanvas.Refresh();
}

If the user clicked the left mouse button, then the code adds a new point to the list. If the user is not currently drawing a new polygon, then the code creates a new points list and sets Drawing to true to indicate that we are now drawing a new polygon.

The code then adds the new point to the list.

If the user clicked the right mouse button, then the program sets Drawing to false to indicate that we are done creating the new polygon.

The event handler finishes by refreshing the picCanvas PictureBox to make the following Paint event handler execute.

private void picCanvas_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    e.Graphics.Clear(picCanvas.BackColor);

    // See if we are drawing a new polygon.
    if (Drawing)
    {
        // Draw the polygon so far.
        if (Points.Count > 1)
            e.Graphics.DrawLines(Pens.Blue, Points.ToArray());
        DrawLineArrows(e.Graphics, Pens.Blue, Points,
            Points.Count - 1);
    }
    else
    {
        // Draw the finished polygon.
        if (Points.Count > 2)
        {
            FillMode fill_mode;
            if (radWinding.Checked)
                fill_mode = FillMode.Winding;
            else
                fill_mode = FillMode.Alternate;
            e.Graphics.FillPolygon(Brushes.LightBlue,
                Points.ToArray(), fill_mode);
            e.Graphics.DrawPolygon(Pens.Blue, Points.ToArray());
        }

        DrawLineArrows(e.Graphics, Pens.Blue, Points, Points.Count);
    }

    foreach (Point point in Points)
    {
        DrawDot(e.Graphics, Brushes.White, Pens.Black, point);
    }
}

If the user is currently drawing a polygon, the code invokes the Graphics object’s DrawLines method to draw the polygon’s edges. It does not connect the final point to the first point, and it does not fill the result. The code then calls the DrawLineArrows method described shortly to draw arrow indicators on the edges.

If the user is not drawing a new polygon, the code examines the radio boxes to see which one is checked and sets the variable fill_mode accordingly. The program then calls the Graphics object’s FillPolygon method, passing it fill_mode to indicate how the polygon should be filled. The code then uses the DrawPolygon method to draw the polygon’s edges, and then uses DrawLineArrows to draw arrow indicators on the edges.

After it has drawn and/or filled the polygon, the code uses the DrawDot method to draw dots on the polygon’s vertices.

The following code shows the DrawLineArrows method.

// Draw a sequence of line arrowheads.
private void DrawLineArrows(Graphics gr, Pen pen,
    List<Point> points, int num_segments)
{
    for (int i = 0; i %lt; num_segments; i++)
    {
        int j = (i + 1) % points.Count;
        DrawArrowhead(gr, pen, points[i], points[j]);
    }
}

This method loops through adjacent pairs of points and calls the following DrawArrowhead method to draw a direction indicator in the middle of the segment connecting the points.

// Draw an arrowhead in the middle of the
// line segment showing its direction.
private void DrawArrowhead(Graphics gr, Pen pen, Point p1, Point p2)
{
    float dx = p2.X - p1.X;
    float dy = p2.Y - p1.Y;
    float dist = (float)Math.Sqrt(dx * dx + dy * dy);
    dx /= dist;
    dy /= dist;
    const float scale = 4;
    dx *= scale;
    dy *= scale;
    float p1x = -dy;
    float p1y = dx;
    float p2x = dy;
    float p2y = -dx;
    float cx = (p1.X + p2.X) / 2f;
    float cy = (p1.Y + p2.Y) / 2f;
    PointF[] points =
    {
        new PointF(cx - dx + p1x, cy - dy + p1y),
        new PointF(cx, cy),
        new PointF(cx - dx + p2x, cy - dy + p2y),
    };
    gr.DrawLines(pen, points);
}

This method calculates the vector <dx, dy> between the start and end points. It finds the distance between the points and normalizes dx and dy so the vector has length 1. It the multiples those values by 4 to scale the result to length 4.

Next the code calculates two perpendicular vectors <p1x, p1y> and <p2x, p2y>. One of those vectors points to the line’s left and the other to the right.

The program then find the point (cx, cy) that is halfway between the two original points. It then adds the components of the vector along the segment <dx, dy> and the perpendicular vectors to find the points that define the arrowhead. The method finishes by drawing the lines that make up the arrowhead.

The last helper method used in the earlier code is the following DrawDot method.

// Draw a dot at this point.
private void DrawDot(Graphics gr, Brush brush, Pen pen, PointF point)
{
    const float radius = 3;
    RectangleF rectf = new RectangleF(
        point.X - radius,
        point.Y - radius,
        2 * radius, 2 * radius);
    gr.FillEllipse(brush, rectf);
    gr.DrawEllipse(pen, rectf);
}

This method simply fills and then outlines a circle at a specified point.

Conclusion

This post explains the difference between the Alternate (Odd/Even) and Winding (Non-Zero) fill modes. You can use the example program to draw polygons and then trace rays from points to see whether those points should be be shaded depending on the fill modes that you select.

It seems like there should be an addition to the fill modes that fills “the whole polygon.” When I have time I may try to write a method to do that.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in drawing, graphics | Tagged , , , , , , , , | Leave a comment

Display COVID-19 data for US states in C#


[COVID-19]

The example Graph world total COVID-19 cases, deaths, and recoveries in C# lets you view and compare COVID-19 data for countries around the world. This example lets you compare data for the US states and territories.

I asked in previous posts for people to let me know if they found time-sequence data for the states, and Adam Kelly did on The COVID Tracking Project.

Not surprisingly their data is not in the exact same format as the data used by my earlier examples, so this example needs to load and process its data differently. The same basic technique or loading the data in a CSV file still works, however, so I won’t describe the process here in detail.

I also don’t have time right now to explain how this program works in detail. Even worse, I have not had time to thoroughly test the program so it may contain more than my usual number of bugs. 😉 If you find a bug, please note it in the comments below.

The program downloads its data from this URL: https://covidtracking.com/api/v1/states/daily.csv. Like the previous programs, it saves today’s data in a file named after the date (as in state_data2020_05_16.csv) and it doesn’t download the data if a file with that name already exists.

This program is different from the earlier ones because it lets you display multiple kinds of data simultaneously. For example, it lets you display the number of positive and negative test results at the same time. For example, the following picture shows positive (bottom) and negative (top) tests for New York.


[COVID-19]

Notice how the negative tests curve is slightly upward curving. That indicates that New York is continuing to expand testing, producing a greater number of tests each day.

Also notice that the positive tests curve is downward curving, showing that New York is recording a smaller number of new COVID-19 cases each day. The two curves together are a sign that New York is starting to stabilize.

This picture also shows an artifact of the data. Notice that the top curve ends with a small horizontal section. That could be due to the last two days having exactly the same values, but it may also be due to the fact that the data has not been updated for the last day. I would not assume that the curve is actually flat, particularly if the rest of the curve does not seem to be approaching horizontal.

Note also that the data may be spotty or unreliable. In fact, the CSV file containing the data even has a dataQualityGrade column that indicates the quality of the data for each row. The example program does not do anything with those values, but you might want to look at them if you find a result that you want to study more closely.

Right now it looks like the only states where the number of confirmed cases is starting to slow are VT, AK, HI, MT, NJ, and NY. The following picture shows the numbers of confirmed COVID-19 cases per million in those states except NY and NJ. (Those two states have had so many cases that including them skews the scale so much that you can’t really see the others.)


[COVID-19]

Most of the other states don’t look like their curves are leveling out. For example, the following picture shows the number of confirmed COVID-19 cases per million for WI, one of the states that has been most vocal about loosening restrictions.


[COVID-19]

You can use the example program to see how different states are doing.

One topic that I also think interesting is how the numbers of cases or fatalities relates to the restrictions in place in each state. For example, Hawaii has tight restrictions and an extremely low case rate. In contrast, Indiana has relatively loose restrictions and a much higher death rate.

The web site WalletHub posted the following picture showing ranking of state restriction level plotted against deaths.


[COVID-19]

You can go to this WalletHub page to see the actual chart, which is interactive and has tooltips.

Some parts of the picture make sense. I suspect the states in the upper right corner, such as NY and NJ, are there because they got hit hard early on and then introduced strict restrictions to fight their ongoing emergencies.

Hawaii’s position is also understandable. They have some very tight restrictions and very few deaths.

I might guess that some of the states closer to the lower left corner are there because of geography. For example, MT and UT are less densely populated than many other states so the coronavirus may not spread as quickly there. Similarly AK and WY are sparsely populated and they, too, have relatively low death rates.

I would like to see a version of the WalletHub plot with deaths per million rather than “Death Rate Ranking.” If the ranking simply means which country is best, second best, etc., then we might be able to learn a bit more by plotting actual death rates. For example, on the plot PA and NY are so close that they touch, but their numbers of deaths per million are very different with 1,147 deaths per million in NY and 339 deaths per million in PA. Maybe I’ll try to build a program that makes this comparison when I have time.

Meanwhile, download the example, experiment with it, and post any interesting findings in the comments below.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in drawing, graphics | Tagged , , , , , , , , , , , , , , , , , , , | Leave a comment

Make a random tree of generic TreeNode objects in C#

[random tree]

The example Handle generic TreeNode mouse events in C# explains how to build a tree where each node is represent by a TreeNode object. Each TreeNode contains its own object that determines how the node is drawn. This example the previous one to draw random trees.

The idea is simple. The program adds the tree’s nodes to a list. When it needs to add a new node to the tree, it picks a random node from the list to be the new node’s parent.

When the program starts, it uses the following code to build the random tree.

// The root node.
private TreeNode<CircleNode> Root;

// Make a tree.
private void Form1_Load(object sender, EventArgs e)
{
    // Make a list of all nodes.
    List<TreeNode<CircleNode>> nodes =
        new List<TreeNode<CircleNode>>();

    // Make the root node.
    Root = new TreeNode<CircleNode>(new CircleNode("Root"));
    nodes.Add(Root);

    // Make random child nodes.
    Random rand = new Random();
    for (char letter = 'A'; letter <= 'Z'; letter++)
    {
        // Make a new node.
        TreeNode<CircleNode> new_node =
            new TreeNode<CircleNode>(new CircleNode(letter.ToString()));

        // Pick a random parent node.
        int i = rand.Next(0, nodes.Count - 1);

        // Add the new node to the parent's children.
        nodes[i].AddChild(new_node);

        // Add the new node to the nodes list.
        nodes.Add(new_node);
    }

    // Arrange the tree.
    ArrangeTree();
}

This code declares the Root variable at the class level outside of any methods.

The form’s Load event handler creates a list of TreeNode objects named nodes. This list will hold references to all of the tree’s nodes.

Next the code creates the root node and adds it to the nodes list. It then loops over the letter A to Z. For each letter it creates a new node to display that letter. It then uses a Random object to pick a random index in the nodes list. It adds the new node to the children of the randomly selected node. It also adds the new node to the nodes list so it might have children later.

After it has finished building the tree, the event handler calls the ArrangeTree method just as the previous version of the program does.

The rest of the program is the same as the previous version. Download the example and see the previous post to see details such as how the program lays out and draws the tree.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in classes, generic, OOP | Tagged , , , , , , , , , , , , | Leave a comment

Quick COVID-19 update


[COVID-19]

Recently President Trump claimed that the United States and Germany were tied for the fewest COVID-19 deaths per capita in the world. The example Graph world total COVID-19 cases, deaths, and recoveries in C# allows you to check that claim in a matter of seconds.

The picture above shows the example program displaying the graphs of deaths per million for the United States and all countries with fewer deaths per million. There are only 10 countries that have a higher number of deaths per million. Of those, San Marino (population 33,785) and Andorra (77,006) have such small populations that a single event may dominate their results. Each of those countries has reported only between 40 and 50 deaths.

It is possible that some other countries have higher numbers of deaths per million than the United States, but their reporting isn’t reliable. For example, Eritrea has only reported 39 cases, has not reported a new case in almost a month, and had reported no deaths. There’s little hope of knowing what’s going on in that country.

In addition to seeing that the United States ranks 11th-from-last in the picture above, you can also see that Germany is only 7 spots better off. That puts them far below the United States in terms of deaths per million, but still higher than the majority of other countries.

Download the earlier example to study the data yourself.


Follow me on Twitter   RSS feed   Donate




Posted in drawing, graphics | Tagged , , , , , , , , , , , , , , , , | Leave a comment

Prevent “underlying connection was closed” errors in C#


[underlying connection was closed]

This example shows how to fix the error “The underlying connection was closed” when downloading a response from a web page.

Background

The basic approach for downloading a result from a web page is simple. Create a new WebClient object and use its DownloadString to download a URL result as a string. The following code snippet shows this technique.

using (WebClient client = new WebClient())
{
    return client.DownloadString(url);
}

This works fine for some web sites, but for others you get one of the following error messages.


[underlying connection was closed]

This seems to be caused by the web site using one of the newer security protocols. The solution is to set the ServicePointManager class’s static SecurityProtocol property to an appropriate value.

In older versions of .NET, that enumeration has two values, Ssl3 (Secure Socket Layer 3.0) and Tls (Transport Layer Security 1.0). Newer versions of the enumeration also include the values Tls11 (TLS 1.1), Tls12 (TLS 1.2), and Tls13 (TLS 1.3).

In Visual Studio 2019 with .NET Framework 4.5, I managed to get the earlier code snippet to work by setting SecurityProtocol to SecurityProtocolType.SystemDefault. That value has the numeric value 0, but for some reason setting this property to 0 doesn’t seem to work in Visual Studio 2008. Presumably that’s because of some difference in the Framework versions.

Fortunately explicitly setting the value to allow the TLS 1.1 and TLS 1.2 protocols seems to work.

A Fake Enumeration

To avoid using magic numbers, I wanted to create an enumeration holding the possible protocol values. Unfortunately the SecurityProtocol property expects a value of type SecurityProtocolType. If you set it equal to an enumeration that you define, Visual Studio complains that it cannot convert your enumeration into the necessary type.

In C# you can specify an enumeration’s type, but it must be an integral type such as int, uint, or short, so you cannot make it have the type SecurityProtocolType.

To work around that, I created the following class to define the possible values.

public class Protocols
{
    public const SecurityProtocolType
        protocol_SystemDefault = 0,
        protocol_Ssl3 = (SecurityProtocolType)48,
        protocol_Tls = (SecurityProtocolType)192,
        protocol_Tls11 = (SecurityProtocolType)768,
        protocol_Tls12 = (SecurityProtocolType)3072;
}

This class simply defines the protocol values listed on Microsoft’s web page SecurityProtocolType Enum. (Interestingly this is one of the pages that will not return a result unless you set the SecurityProtocol property.)

The example’s Form1_Load event handler uses the following statement to set the SecurityProtocol.

ServicePointManager.SecurityProtocol =
    Protocols.protocol_Tls11 | Protocols.protocol_Tls12;

The SecurityProtocol is a mask, so you can use the | operator to allow multiple protocols. This code allows TLS 1.2 and TLS 1.3.

Conclusion

So that’s the technique. Set ServicePointManager.SecurityProtocol to a combination of the protocols that you want to allow when downloading a web result. The Protocols class defines values that you can use almost as if Protocols were an enumeration.

Download the example to see additional details and to experiment on your own.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in internet, web | Tagged , , , , , , , , , , , , | Leave a comment

Graph world total COVID-19 cases, deaths, and recoveries in C#


[COVID-19]

My previous COVID-19 posts examined cases, deaths, and recoveries for different countries. I recently wanted to look at the world-wide totals, so I made this modification.

Making changes to handle the world totals separately would have been a lot of work, so instead I simply made a new artificial country named All. When the program loads the data for the countries, it adds all of the values to the All country’s data. For example, the following code shows how the program loads case data with the new pieces highlighted in blue.

// Save the world values.
float[] all_values = new float[num_dates];

// Load the country data.
const int country_col = 2;
for (int country_num = 2; country_num <= max_row; country_num++)
{
    // Get the country's name.
    string country_name = fields[country_num, country_col].ToString();

    // Get or create the country's CountryData object.
    CountryData country_data =
        GetOrCreateCountryData(country_name, num_dates);

    // Add to the country's data.
    for (int col = 1; col <= num_dates; col++)
    {
        // Add the value to the country's total.
        country_data.Cases[col - 1] +=
            (int)(double)fields[country_num, col + first_date_col - 1];

        all_values[col - 1] +=
            (int)(double)fields[country_num, col + first_date_col - 1];
    }
}

CountryData all_data =
    GetOrCreateCountryData("All", num_dates);
all_data.Cases = all_values;

The code first creates an array to hold the total values. It then loops through the countries as before. It gets the CountryData object for each country and then loops through the dates for which data exists, adding each value to the country’s data. It also adds the new value to the all_values total.

After it has finished loading the data, the program gets the CountryData for the All country and saves the total that it created in that object’s Cases value.

The code that loads the death and recovery data works similarly. Download the example to see the details.

The picture at the top of the post shows deaths per resolution for the world, US, and Italy. In the world data, the number seems to be leveling off a bit below 20%. All three curves trend downward over time, possibly because increased testing is raising the number of known cases and thus decreasing the ratio of deaths to resolutions. To think of this in another way, increased testing means a greater number of minor infections are being recorded.

The following picture shows cases per million.


[COVID-19]

The curves for Spain and Italy show a slight downward curve near their ends indicating that the rate of increase in cases may be slowing.

The US curve seems to be roughly linear right now, indicating that the number of new cases is roughly the same each day. Unfortunately that has been the trend for quite a while so the number of cases does not seem to be slowing. At least it’s not curving upward as an unchecked exponential growth curve would be.

The world curve also seems roughly linear, although with a lower slope. The linear shapes of the US and world curves seem to imply that the pandemic is far from over. The lower slope on the world curve may mean it’s taking longer for the virus to penetrate some parts of the world, or it could reflect weak testing in parts of the world so the recorded number of cases isn’t rising as quickly as the actual number.

Download the example and experiment with it. If you learn anything interesting, please post a note in the comments below. Also post a comment if you know of a data source where we can get similar data for the US states, or any other localities that you think would be interesting.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in drawing, graphics | Tagged , , , , , , , , , , , , , , , , | 2 Comments

Understand bitwise operators in C#

[bitwise operators]

The examples Make an efficient priority queue class in C#, Part 1 and Make an efficient priority queue class in C#, Part 2 explain how to make a heap-based priority queue. Those examples use a FindMsb method that uses bitwise operators. This post provides some extra explanation about how bitwise operators work.

Binary Values

First, how does binary work? When you write a number in binary, suppose its bits are ABC…LMN. Each digit represents a power of 2. The rightmost digit represents 20, the next digit represents 21, the third from the right digit represents 22, and so forth.

This is similar to the way it is in base 10 where digits represent powers of 10. For example, in the number 123, the 3 represents 100 = 1, the 2 represents 101 = 10, and the 1 represents 102 = 100. So the value 123 equals:

123
    = 1 * 102 + 2 * 101 + 3 * 100
    = 1 * 100 + 2 * 10 + 3 * 1
    = 123

Now let’s return to binary and consider the value 1101. From right-to-left the digits represent powers of 2: 20, 21, 22, and 23. So the value 1101 equals:

1101
    = 1 * 23 + 1 * 22 + 0 * 21 + 1 * 20
    = 1 * 8 + 1 * 4 + 0 * 2 + 1 * 1
    = 8 + 4 + 0 + 1
    = 13

Because the leftmost digit represents the biggest power of 2, it is called the most significant digit. Similarly because the rightmost digit represents the smallest power of 2, it is called the least significant digit.

Sometimes we use those terms to mean the most or least non-zero significant digit. For example, in C# an int has 32 binary digits. In the value 000…01101, the true most significant digit is the leftmost digit in position 32. The most significant non-zero digit is the leftmost 1 in position 4 (if we number the digits 1, 2, 3, 4 from right-to-left).

Bitwise Operations

C# has six bitwise operators that manipulate a value’s bits. The &, |, and ^ operators combine two values by comparing them bit-by-bit. For example, if two values have a 1 in their corresponding bits, then the & “and” operator makes the corresponding result bit equal to 1. If either of the values is 0, then the corresponding result bit is 0.

Or | “or” operator sets the result bit if either of the input bits is 1.

The ^ “xor” (exclusive or) operator sets the result bit if exactly one but not both of the input bits is 1.

Here are some examples.

  01100101
& 11011001
----------
  01000001

  01100101
| 11011001
----------
  11111101

  01100101
^ 11011001
----------
  10111100

The << “left shift” operator shifts the bits in a value a certain number of places to the left. For example, 11011001 << 2 shifts the bits two places to the left to give 01100100. Bits that are shifted off of the left end are discarded and new bits added on the right are set to 0.

The >> “righ shift” operator shifts the bits in a value a certain number of places to the right. For example, 11011001 << 2 shifts the bits two places to the right to give 00110110. Bits that are shifted off of the right end are discarded and new bits added on the left are set to 0.

The final bit operator is the complement operator ~. It flips the bits in the input, replacing 1’s with 0s and vice versa. For example, ~11011001 is 00100110.

Parsing and Printing Binary Values

C# does not provide easy conversion operators for working with binary values. For example, you can easily convert between strings and integers relatively easily. The operators for working with binary values are about as easy to use, they’re just harder to find because they’re not used as often.

To convert from a binary string of 0s and 1s into an integer data type, you use one of the Convert class’s static conversion methods. Different methods convert the string into different integer data types. The methods you can use include ToByte, ToSByte, ToInt16, ToInt32, ToInt64, ToUInt16, ToUInt32, and ToUInt64.

The second parameter to the convert method indicates the base used by the value. To convert a binary value, this parameter should be 2. (You can also use 16 to convert from hexadecimal.) For example, the following code converts the binary string “101101” into a 16-bit integer.

int value = Convert.ToInt32("101101", 2);

To create a binary string representation of a value, use the Convert class’s ToString method, giving it the second parameter 2 to indicate that it should use a binary format. (You can use 16 here to display a hexadecimal value.) For example, the following code converts value into a binary string.

string result = Convert.ToString(value, 2);

Masking

Sometimes you may want to set specific bits to 0 or 1 in a value. You can do that by using the & and | operators to combine the value with a mask. The mask value defines the bits that will be set or cleared.

For example, suppose the mask has binary value 100. If you use the & operator to combine a value with the mask, then the result has every bit cleared except the third bit. That bit will be 1 if the corresponding bit is 1 in the input value.

Now suppose you use the | operator to combine the same mask with a value. The mask’s third bit is 1, so the third bit of the result will also be 1. Any bits in the input value that are 1 will also remain 1.

The second example (that uses |) shows how to set a specific bit. To clear a specific bit, you use & as in the first technique. Set all of the mask’s bits to 1 except the bit(s) that you want to clear and then use & to combine the mask with the input value.

It’s often inconvenient to specify the mask by giving all of the 1s that you want to preserve. One way to simplify that is to specify the bit that you want to clear and invert the mask. For example, the following pseudocode clears the third bit from the right in the input.

input = input & ~(0100)

This operation takes the mask value 01000, inverts it to get 10111, and then uses the & operator to clear the input’s third bit.

This makes sense when you write the values in binary, but C# doesn’t let you work in binary. (Well, the latest version does let you define constants in binary.) Another technique that is useful for creating mask values is to apply the << operator to the value 1. The << operator shifts the single set bit in the value 1 to the left by the number of positions that you specify.

For example, to place a 1 in the third bit, you can shift the value 1 by 2 digits to the left. The following code clears the input value’s third bit much as the preceding value does but using actual C# code.

input = input & ~(1 << 2)

Those techniques let you set or clear specific bits. You may also want to know whether a specific bit is set. To do that, use & to compare the input to a mask that has a 1 in the bit that you want to check. For example, the following code sets fifth_bit_set to indicate whether the input value’s fifth bit is set to 1.

bool fifth_bit_set = (input & (1 << 4)) != 0;

By using these techniques, you should be able to write methods that get, set, or clear specific bits. I’ll leave that as an exercise for you.

LSB and MSB

Because the leftmost bit in a value represents the largest power of 2, changes to it make the biggest difference to the value. For that reason this bit is called the most significant bit (MSB). Similarly because the rightmost bit represents the smallest power of 2, it is called the least significant bit (LSB).

Note that signed integers use the leftmost bit as the sign bit. If an integer has a 1 in its leftmost bit, then it represents a negative number. That’s important for representing negative numbers, but you can usually ignore this fact when performing bitwise arithmetic. When you’re using bitwise operators, a bit is a bit. You’ll only notice weirdness when you treat the binary values as integers.

Often when we talk about the LSB and MSB we mean the largest or smallest non-zero bit. For example, in the value 00111010, the MSB is in position 6 (as numbered starting with 1 on the right) and the LSB is in position 2.

The examples mentioned earlier use the following method to find a value’s MSB.

// Return the number's most significant bit.
private int FindMsb(int number)
{
    for (int i = 31; i >= 0; i--)
        if ((number & (1 << i)) != 0) return i;
    return -1;
}

By now you should be able to trace through this method to see what it does.

The code first loops from 31 down to 0. For each value, it shifts the value 1 that many places to the left to create a mask with a 1 in the corresponding position. For example, the first time through the loop the 1 is in the 32nd bit at the far left of the 32-bit integer.

The code then uses the & operator to compare the input number to the mask to see if it has a 1 in that position. If the code finds the 1, it returns the bit position. (This time numbered starting with 0 in the rightmost position.)

If you like, you should be able to write a similar method that finds the rightmost non-zero bit in a number. Or you should be able to write a method that makes a list or array containing the positions of all of the non-zero bits.

The Example

When you change this example’s input values or select a new operator, the following code executes.

private void Calculate()
{
    txtResult.Clear();
    txtDecimalOperand2.Clear();
    txtDecimalOperand1.Clear();
    txtDecimalResult.Clear();

    try
    {
        // Convert the binary inputs into integers.
        int operand1 = Convert.ToInt32(txtOperand1.Text, 2);
        int operand2 = Convert.ToInt32(txtOperand2.Text, 2);

        // Calculate the result.
        int result = 0;
        switch (cboOperator.Text)
        {
            case "&":
                result = (operand1 & operand2);
                break;
            case "|":
                result = (operand1 | operand2);
                break;
            case "^":
                result = (operand1 ^ operand2);
                break;
            case "<<":
                result = (operand1 << operand2);
                break;
            case ">>":
                result = (operand1 >> operand2);
                break;
            case "~":
                result = ~operand1;
                break;
        }

        // Display the result in binary.
        txtResult.Text = Convert.ToString(result, 2);

        // Show the values in decimal.
        txtDecimalOperand1.Text = operand1.ToString();
        txtDecimalOperand2.Text = operand2.ToString();
        txtDecimalResult.Text = result.ToString();
    }
    catch
    {
    }
}

The method first clears the display text boxes and then uses a try catch block to ignore errors. (In case you enter something invalid in the input text boxes.)

The code then uses Convert.ToInt32 to turn the binary that you entered into integers.

Next the code uses a switch statement to determine which operator is should use and it applies the corresponding operator.

Note that the shift operators adjust the bits in the first operand by the value of the second operand. To see a meaningful result, start by setting the shift to something relatively small like 10. Also notice what happens if you make the shift really large. In particular, see what happens when the shift is 32 or 33.

Also note that the ~ operator inverts the first operand and the second operand is ignored.

After it calculates the result, the code uses Convert.ToString to display the result in binary.

The method finishes by displaying the operands and result in decimal.

Conclusion

This post explained the main ideas that you need to know to perform bitwise operations. You can use these techniques to get, set, and clear bits in C# programs.

Download the example and experiment with it to test your understanding and to learn about other details, like what happens if you shift a value by 32 bits.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in algorithms, mathematics | Tagged , , , , , , , , , , , | Leave a comment

Make bitmap extension methods that resize bitmaps in C#

[bitmap extension methods]

The post Resize pictures in a directory to specific widths or heights in C# lets you resize all of the pictures in a directory. This example extracts the key method that resizes files and places it in a new Bitmap extension method.

This example actually makes two new extension methods. The first version resizes a bitmap and returns a new bitmap with a given width and height.

The second version resizes the bitmap’s width, height, or both. If you do not want to specify both the width and height, the method calculates the one that you do not specify so it resizes the image without distortion.

Extension Classes

Recall that extension methods must be public static and must be contained inside classes that are also public static. This example places both versions of the Resize bitmap extension methods in the Extensions class. The following code shows the class’s declaration and basic structure.

public static class Extensions
{
    // Return a resized version of the bitmap.
    public static Bitmap Resize(this Bitmap bm,
        int new_width, int new_height)
    {
        ...
    }

    // Resize the image, scaling uniformly if
    // set_width and set_height are not both true.
    public static Bitmap Resize(this Bitmap bm,
        bool set_width, bool set_height, int new_width, int new_height)
    {
        ...
    }
}

You can see that the class and its two bitmap extension methods are declared public static.

The first parameter to each of the extension methods is this Bitmap bm. That means the Bitmap class is the class that these methods extend. For example, if my_picture is a bitmap, then you could use the following code to make a copy of that bitmap that has width 512 and height calculated to resize without distortion.

Bitmap new_bitmap = my_picture.Resize(true, false, 512, 0);

This stes the new image’s width to 512 and its height to the appropriate value to prevent distortion.

The following sections describe the two bitmap extension methods.

Resize Version 1

The following code shows the first version of the Resize bitmap extension methods.

// Return a resized version of the bitmap.
public static Bitmap Resize(this Bitmap bm,
    int new_width, int new_height)
{
    // Make rectangles representing the original and new dimensions.
    Rectangle src_rect = new Rectangle(0, 0, bm.Width, bm.Height);
    Rectangle dest_rect = new Rectangle(0, 0, new_width, new_height);

    // Make the new bitmap.
    Bitmap bm2 = new Bitmap(new_width, new_height);
    using (Graphics gr = Graphics.FromImage(bm2))
    {
        gr.InterpolationMode =
            InterpolationMode.HighQualityBicubic;
        gr.DrawImage(bm, dest_rect, src_rect,
            GraphicsUnit.Pixel);
    }

    return bm2;
}

This method takes as parameters a new desired with and height. It makes rectangles representing the image’s original and desired dimensions.

The code then creates a new bitmap of the desired size and makes an associated Graphics object. It sets that object’s InterpolationMode to smoothly resize the image and uses the DrawImage method to draw the original image onto the new bitmap. The method finished by returning the new bitmap.

Resize Version 2

The previous method returns a bitmap with the desired dimensions even if that distorts the image. The following version calculates the width or height to prevent distortion.

// Resize the image, scaling uniformly if
// set_width and set_height are not both true.
public static Bitmap Resize(this Bitmap bm,
    bool set_width, bool set_height, int new_width, int new_height)
{
    // Calculate the new width and height.
    if (!set_width) new_width = bm.Width * new_height / bm.Height;
    if (!set_height) new_height = bm.Height * new_width / bm.Width;

    // Resize and return the image.
    return bm.Resize(new_width, new_height);
}

If the set_width parameter is false, then the method calculates the new width to match the scale determined by the original and new heights.

Similarly if the set_height parameter is false, the method calculates the new height to match the scale determined by the original and new widths.

If both set_width and set_height are true, the code uses them as they are passed into the method. If both of those parameters are false, then the method may produce unpredictable results depending on the values of new_width and new_height. That should probably be treated as an error and you are welcome to add a test for that situation if you like.

After it has calculated new_width or new_height if necessary, the method calls the precious extension method to resize the bitmap and returns the result.

SaveImage

While I was at it, I also added another method to the bitmap extension methods. This method is described in the post Save images with an appropriate format depending on the file name’s extension in C#. The following code shows the new extension method.

// Save the file with the appropriate format.
public static void SaveImage(this Image image, string filename)
{
    string extension = Path.GetExtension(filename);
    switch (extension.ToLower())
    {
        case ".bmp":
            image.Save(filename, ImageFormat.Bmp);
            break;
        case ".exif":
            image.Save(filename, ImageFormat.Exif);
            break;
        case ".gif":
            image.Save(filename, ImageFormat.Gif);
            break;
        case ".jpg":
        case ".jpeg":
            image.Save(filename, ImageFormat.Jpeg);
            break;
        case ".png":
            image.Save(filename, ImageFormat.Png);
            break;
        case ".tif":
        case ".tiff":
            image.Save(filename, ImageFormat.Tiff);
            break;
        default:
            throw new NotSupportedException(
                "Unknown file extension " + extension);
    }
}

This code uses the Path class’s GetExtension method to get the file’s extension (such as .png or .gif) and converts it to lower case. It then uses a switch statement to save the image in the format that is appropriate for that file extension.

LoadBitmap

This example loads bitmap files in a using block so they are automatically disposed when the program is done with them. In contrast some examples need to keep an image for a prolonged period of time. During that time the program may keep the image’s file locked so you cannot edit or delete it.

One of the tools I use fairly frequently is a method to open a file without keeping its file locked. This example doesn’t really need that feature, but I decided to add it to the Extensions class anyway so I could find it easily later. The following code shows the method.

// Load a bitmap without locking its file.
public static Bitmap LoadBitmap(string filename)
{
    using (Bitmap bm = new Bitmap(filename))
    {
        return new Bitmap(bm);
    }
}

The method loads the bitmap in a using block so it is automatically disposed when the method ends. Inside the block, the code make a new bitmap created by copying the first one. It then returns this new bitmap.

Unfortunately there is no way to add a static extension method to a class, so we can’t make this a method of the Bitmap class. We could make it a non-static Bitmap extension, but it seems silly to make you create an instance of the Bitmap class just to create a new Bitmap. So this method is part of the Extensions class. You can use it as in the following statement.

Bitmap bm = Extensions.LoadBitmap(file_info.FullName);

Conclusion

These bitmap extension methods allow you to easily resize bitmaps, load bitmaps, and save them in appropriate formats. If you do those things as often as I do, you’ll want to add these methods to your programming toolkit.

Download the example program to see additional details.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in extensions, files, graphics | Tagged , , , , , , , , , , , , , , , , | 2 Comments

Resize pictures in a directory to specific widths or heights in C#

[resize pictures]

The post Resize pictures in a directory in C# lets you resize all of the pictures in a directory but it only scales the images. This example lets you resize pictures so they have a given width, height, or both. If you specify only one of the width or height, the program calculates the other value so the image is not distorted.

ResizeBitmap

After some preliminaries, the program loops through the files in the selected directory and calls the following ResizeBitmap method for each.

// Resize a bitmap to the given dimensions.
// If one dimension is omitted, scale the image uniformly.
private Bitmap ResizeBitmap(Bitmap bm,
    bool set_width, bool set_height,
    int new_width, int new_height)
{
    Rectangle from_rect =
        new Rectangle(0, 0, bm.Width, bm.Height);

    // Calculate the image's new width and height.
    int wid2, hgt2;
    if (set_width)
        wid2 = new_width;
    else
        wid2 = bm.Width * new_height / bm.Height;
    if (set_height)
        hgt2 = new_height;
    else
        hgt2 = bm.Height * new_width / bm.Width;

    // Make the new image.
    Bitmap bm2 = new Bitmap(wid2, hgt2);

    // Draw the original image onto the new bitmap.
    Rectangle dest_rect = new Rectangle(0, 0, wid2, hgt2);
    using (Graphics gr = Graphics.FromImage(bm2))
    {
        gr.InterpolationMode =
            InterpolationMode.HighQualityBicubic;
        gr.DrawImage(bm, dest_rect, from_rect,
            GraphicsUnit.Pixel);
    }

    return bm2;
}

This method first creates a rectangle representing the area that will be copied. That includes the entire input image.

It then calculates the new image’s width and height. If the set_width parameter is true, the program sets the new width equal to the value in parameter new_width. If set_width is not true, the code calculates a new width that uses the same scale needed to map the original height to the new height.

The method then repeats the same steps to calculate the new image’s height.

Note that this code scales one dimension if it is not specified. If both dimensions are specified, then it uses both of them for the new image.

Having calculated the new image’s dimensions, the code creates the new Bitmap and makes an associated Graphics object. It then uses that object’s DrawImage method to copy the original bitmap into the new one.

The method finishes by returning the new bitmap. The main program then saves the new Bitmap in a file with the same name as the original file with “_s” added at the end before the file extension.

Conclusion

This example loops through the graphic files in a directory and resizes them all. The ResizeBitmap method could be useful in other programs, too. For example, you might like to resize a single image so it has a particular width. That makes the ResizeBitmap method a useful addition to your programming toolkit.

Download the example program to see additional details such as how the program loops through the files that it converts.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in files, graphics, image processing | Tagged , , , , , , , , , , , , , , , | 1 Comment

Use code to make a slideshow in C# and WPF

This is example shows how to make a slideshow in WPF. Unlike all of the examples I’ve seen on the internet, however, this one uses C# code rather than XAML. It’s actually fairly simple, it just took a long time to figure out how to do it.

The main takeaway from this example is a better understanding off how WPF storyboards work.

The Code

The following XAML code shows how the program builds its single Image control.

<Grid>
    <Image Margin="5,5,5,5" Name="imgPicture" Stretch="Uniform" />
</Grid>

This code simply makes an Image control that fills the program’s main Grid control minus a five-pixel margin.

The program executes the following code when it starts.

private List<BitmapImage> Images = new List<BitmapImage>();
private int ImageNumber = 0;
private DispatcherTimer PictureTimer = new DispatcherTimer();

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    DirectoryInfo dir_info = new DirectoryInfo(Environment.CurrentDirectory);
    foreach (FileInfo file_info in dir_info.GetFiles())
    {
        if ((file_info.Extension.ToLower() == ".jpg") ||
            (file_info.Extension.ToLower() == ".png"))
        {
            Images.Add(new BitmapImage(new Uri(file_info.FullName)));
        }
    }

    // Display the first image.
    imgPicture.Source = Images[0];

    // Install a timer to show each image.
    PictureTimer.Interval = TimeSpan.FromSeconds(3);
    PictureTimer.Tick += Tick;
    PictureTimer.Start();
}

This code starts by creating a list of BitmapImage objects to hold the images that the slideshow will display.

Alternatively you could store the names or URIs of the files instead of pre-loading the images themselves. If the slideshow will display a large number of big images, then you may be unable to load all of the images into memory when the program starts, so it may be better to store only their names or URIs.

However, there is sometimes a delay when loading an image file. If the slideshow loads each image as it is needed, there may be a delay that will mess up the show. To avoid that, you might want the program to pre-load the next image after it displays the current one. That way the program will have time to finish loading the next image before it is needed.

After it creates the list of images, the code defines variable ImageNumber to keep track of the image in the list that is currently being displayed. It also creates a DisplatcherTimer (from the System.Windows.Threading namespace) that will display the images.

When the program’s window loads, the program creates a DirectoryInfo object and loops through the files returned by its GetFiles method. For this example, I added several small images to the project, set their Build Action properties to Content, and set their Copy to Output Directory properties to Copy if Newer. When Visual Studio builds the program starts, it automatically copies the files into the executable directory so the program can find them easily. If you want the program to look for the files in some other directory, pass that directory’s path into the DirectoryInfo constructor.

When it loops through the returned files, if the file’s extension is .png or .jpg, the program uses its name to create a Uri object representing the file’s location, uses that to create a BitmapImage, and adds the image to the Images list.

Next the displays the first image in the imgPicture Image control.

The code then sets the timer’s interval to three seconds so it will display images three seconds apart. In a real slideshow, you might want to make this longer, but I wanted it easy to see in the example program. The code assigns the Tick event handler to handle the timer’s Tick event and then starts the timer.

When the timer’s Tick event occurs, the following code executes.

// Display the next image.
private void Tick(object sender, System.EventArgs e)
{
    ImageNumber = (ImageNumber + 1) % Images.Count;
    ShowNextImage(imgPicture);
}

private void ShowNextImage(Image img)
{
    const double transition_time = 0.9;
    Storyboard sb = new Storyboard();

    // ***************************
    // Animate Opacity 1.0 --> 0.0
    // ***************************
    DoubleAnimation fade_out = new DoubleAnimation(1.0, 0.0,
        TimeSpan.FromSeconds(transition_time));
    fade_out.BeginTime = TimeSpan.FromSeconds(0);

    // Use the Storyboard to set the target property.
    Storyboard.SetTarget(fade_out, img);
    Storyboard.SetTargetProperty(fade_out,
        new PropertyPath(Image.OpacityProperty));

    // Add the animation to the StoryBoard.
    sb.Children.Add(fade_out);


    // *********************************
    // Animate displaying the new image.
    // *********************************
    ObjectAnimationUsingKeyFrames new_image_animation =
        new ObjectAnimationUsingKeyFrames();
    // Start after the first animation has finisheed.
    new_image_animation.BeginTime = TimeSpan.FromSeconds(transition_time);

    // Add a key frame to the animation.
    // It should be at time 0 after the animation begins.
    DiscreteObjectKeyFrame new_image_frame =
        new DiscreteObjectKeyFrame(Images[ImageNumber], TimeSpan.Zero);
    new_image_animation.KeyFrames.Add(new_image_frame);

    // Use the Storyboard to set the target property.
    Storyboard.SetTarget(new_image_animation, img);
    Storyboard.SetTargetProperty(new_image_animation,
        new PropertyPath(Image.SourceProperty));

    // Add the animation to the StoryBoard.
    sb.Children.Add(new_image_animation);


    // ***************************
    // Animate Opacity 0.0 --> 1.0
    // ***************************
    // Start when the first animation ends.
    DoubleAnimation fade_in = new DoubleAnimation(0.0, 1.0,
        TimeSpan.FromSeconds(transition_time));
    fade_in.BeginTime = TimeSpan.FromSeconds(transition_time);

    // Use the Storyboard to set the target property.
    Storyboard.SetTarget(fade_in, img);
    Storyboard.SetTargetProperty(fade_in,
        new PropertyPath(Image.OpacityProperty));

    // Add the animation to the StoryBoard.
    sb.Children.Add(fade_in);

    // Start the storyboard on the img control.
    sb.Begin(img);
}

The Tick event handler increments ImageNumber and then calls the ShowNextImage method. This version takes ImageNumber modulo the number of images, so it repeatedly displays the images forever. If you want the slideshow to run through the image only once, you could disable the timer when ImageNumber equals the number of images. Or you could randomize the list and let ImageNumber wrap around again to zero to display the images again in a new order.

The ShowNextImage method creates a storyboard that makes the slideshow’s current image fade out and then makes a new image fade in. A storyboard is basically a collection that holds timelines such as animations. The storyboard also provides targeting information for those timelines. When the timelines are property animations, as they are in this example, the storyboard tells those animations what properties they will animate.

The ShowNextImage method first creates its storyboard. It then makes a DoubleAnimation object to animate the Image control’s Opacity property. the animation will make that property go from value 1.0 (fully opaque) to 0.0 (fully transparent) over the time span given by the constant transition_time. In this example, I set transition_time to 0.9, so it takes the image 0.9 seconds to fade out.

The code sets the animation’s BeginTime to zero, so the animation starts as soon as the storyboard starts.

Having initialized the animation object, the code uses the Storyboard class’s static SetTarget method to tell the animation that it will be targeting the Image control named img, which is passed into the method as a parameter. It then uses the SetTargetProperty method to tell the animation that it will be targeting the Image control’s Opacity property. You can define the property path in several ways including by using a string. This version uses the dependency property Image.OpacityProperty. (That seems easier in this example because you don’t need to know the path format and you can’t mistype it.)

At this point, the animation knows all it needs to do its job. The program adds it to the storyboard’s Children collection.

Next the program creates a second animation. This time it makes an ObjectAnimationUsingKeyFrames object. This type of animation lets you change a property abruptly from one value to another. The values that this animation uses are stored in DiscreteObjectKeyFrame objects. This is the only kind of animation that makes sense when you are animating a property that is an object. in this example, the animation will swap the Image control’s image. While you can make Opacity range from 1.0 to 0.0, you can’t really make an image slowly transition from one object to another. (well, you could, of course, but the WPF classes aren’t smart enough to know how to transition smoothly between objects in general.)

For this example, the ObjectAnimationUsingKeyFrames object starts running transition_time seconds after the storyboard starts. That makes it start after the first animation finishes.

The program then adds a DiscreteObjectKeyFrame to the animation. The constructor initializes that object’s value to the next image that the slideshow should display. It sets the object’s key time to zero so the object switches the property as soon as the animation starts. In general you could make the ObjectAnimationUsingKeyFrames include several ObjectAnimationUsingKeyFrames objects and they could make the property switch from one value to another at different times during the animation.

After it finishes initializing the ObjectAnimationUsingKeyFrames object, the code adds it to the animation’s KeyFrames collection. It then uses the storyboard’s SetTarget and SetTargetProperty methods to tell the animation that it will be acting on the img control’s Source property. It then adds the new animation to the storyboard.

At this point the program has created two animations, one to fade the image’s Opacity property from 1.0 to 0.0 and a second to switch the control’s image. Next the program creates a new DoubleAnimation to fade the Opacity back from 0.0 to 1.0 so the new image will appear. This is similar to the previous DoubleAnimation except this one starts after the previous animations end.

After it has finished creating the three animations, the program calls the storyboard’s Begin method to start ths storyboard running. That call is asynchronous so the ShowNextImage method returns immediately and the animation continues running on its own schedule.

Conclusion

You may not need a slideshow program, but there’s a good chance that you’ll eventually need to use storyboards in your WPF applications. This example shows how you can use a storyboard to play multiple animations in the same timeline.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in animation, wpf | Tagged , , , , , , | 2 Comments