Tile a bitmap with a string in C#

[bitmap]

I recently needed a bitmap tiled with a string for a book I’m working on, so I wrote this program to make it. The program lets you click on the font name, dimensions, or colors to select those values. When you click on one of those items, the program display an appropriate dialog. For example, if you click on the background color swatch (the swatch on the left), the program executes the following code.

private void picBackground_Click(object sender, EventArgs e)
{
    cdColor.Color = picBackground.BackColor;
    if (cdColor.ShowDialog() == DialogResult.OK)
        picBackground.BackColor = cdColor.Color;
}

This code sets the Color property for the ColorDialog component named cdColor to the color in the picBackground PictureBox control. It displays the dialog and, if you pick a color and click OK, the code updates the PictureBox control’s BackColor property to show the newly selected color.

The other pieces of value selection code are similar. Download the example to see how they work.

When you click the Go button, the following code generates and saves the bitmap.

private void btnGo_Click(object sender, EventArgs e)
{
    DrawText();
}

private void DrawText()
{
    int width = int.Parse(txtWidth.Text);
    int height = int.Parse(txtHeight.Text);

    Bitmap bm = new Bitmap(width, height);
    using (Graphics gr = Graphics.FromImage(bm))
    {
        gr.Clear(picBackground.BackColor);

        using (Brush brush =
            new SolidBrush(picForeground.BackColor))
        {
            string text = txtString.Text;
            SizeF size = gr.MeasureString(text, fdFont.Font);
            for (float y = 0; y < bm.Height;
                y += size.Height * 0.8f)
            {
                float x = y;
                while (x > 0) x -= size.Width;

                while (x <= bm.Width)
                {
                    gr.DrawString(text, fdFont.Font, brush, x, y);
                    x += size.Width;
                }
            }
        }

        bm.Save("Result.png", ImageFormat.Png);
        picImage.Image = bm;
    }
}

The button's Click event handler simply invokes the DrawText method. That method gets the entered width and height. It uses them to create a bitmap of the correct size and creates an associated Graphics object.

The code then clears the bitmap with the color stored in the picBackground control's BackColor property. It then creates a brush that uses the color stored in the picForeground control's BackColor property.

The code gets the desired text and calculates its size. It then enters a loop to draw each line of text. For each line, the program sets x = y to move the new line to the right by the same distance it has been moved down. The code subtracts the string's width until x is at most zero, so the line starts to the left of the visible area.

Next, the code enters a loop that prints the string and moves x to the right by the string's width until the string has reached the right edge of the bitmap.

After it finishes filling the bitmap with text, the program saves the result in a PNG file and displays the bitmap in the picImage PictureBox control.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in algorithms, graphics, image processing | Tagged , , , , , , , , , , | Leave a comment

Color the solutions to the “Find the squares in C#” puzzle

[example]

The post Solve the “Find the squares in C#” puzzle explained how you can find solutions to the puzzle described in the post Puzzle: Find the squares in C#. This example shows how you can color the solutions so squares of the same size have the same color.

The bulk of the program is similar to the one described in Solve the “Find the squares in C#” puzzle. The following paragraphs describe the changes in this example.

First, the new program defines the following array of colors.

// Colors used to draw the squares.
private Color[] Colors =
    { Color.Red, Color.Green, Color.Blue, };

The solution includes only four different sizes of squares, so this array only needs to include four colors. If you are working on a new problem and don’t know how many colors you will need, simply add extra colors to the array so you are sure that you have enough.

To assign colors to squares of different sizes, the program needs to make a list of the possible sizes. It uses the following SideLengths list to keep track of the sizes if finds.

// The solutions' side lengths.
private List SideLengths;

Now when the program finds a new square, it uses the following code to record that square’s size.

// Save the side length.
int side_length =
    (int)PointFDistance(Points[i], Points[j]);
if (!SideLengths.Contains(side_length))
    SideLengths.Add(side_length);

This code uses the PointFDistance method (which simply finds the distance between two points) to get the new square’s side length and truncates the length into an integer. Rounding errors may make the lengths of similar squares not match exactly, but they should be within one unit of each other.

If the truncated length is not yet in the SideLengths list, the code adds it.

The final change to the program draws a square. The following code draws square number index.

// Get the side length.
int side_length = (int)PointFDistance(pts[0], pts[1]);
int index = SideLengths.IndexOf(side_length);

// Make an appropriately colored brush and pen.
Color fill_color = Color.FromArgb(64,
    Colors[index].R,
    Colors[index].G,
    Colors[index].B);
using (Brush brush = new SolidBrush(fill_color))
{
    gr.FillPolygon(brush, pts.ToArray());
}

using (Pen pen = new Pen(Colors[index], 0))
{
    gr.DrawPolygon(pen, pts.ToArray());
}

This code gets the square’s side length and then finds the index of that length in the SideLengths list so it can use that index as an index into the Colors array.

The code then creates a color with the appropriate red, green, and blue components but with an alpha value 64 so the color is semi-transparent. It then fills the square with that color.

The snippet finishes by outlining the square with the original solid color.

If you run the program and click the Show Solutions button, you’ll see that squares of different sizes have different colors. If you click the Show All button, you’ll get a picture similar to the one at the top of this post showing all of the squares on top of each other.


Download Example   Follow me on Twitter   RSS feed   Donate




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

Solve the “Find the squares in C#” puzzle

[puzzle]

This post shows how to solve the puzzle Puzzle: Find the squares in C#. The program howto_square_puzzle_solution uses the following code to define the puzzle’s 11 solutions.

// Small squares.
Solutions.Add(new int[] { 0, 1, 4, 3 });
Solutions.Add(new int[] { 2, 3, 7, 6 });
Solutions.Add(new int[] { 3, 4, 8, 7 });
Solutions.Add(new int[] { 4, 5, 9, 8 });
Solutions.Add(new int[] { 7, 8, 11, 10 });

// Medium squares.
Solutions.Add(new int[] { 0, 4, 7, 2 });
Solutions.Add(new int[] { 1, 5, 8, 3 });
Solutions.Add(new int[] { 3, 8, 10, 6 });
Solutions.Add(new int[] { 4, 9, 11, 7 });

// Big squares.
Solutions.Add(new int[] { 0, 6, 11, 5 });
Solutions.Add(new int[] { 1, 2, 10, 9 });

You can try to find the solutions manually but two of them are fairly hard to spot. The program howto_find_squares uses the following code to find the solutions.

// Find the solutions.
private void FindSolutions()
{
    for (int i = 0; i < Points.Length - 3; i++)
    {
        for (int j = i + 1; j < Points.Length - 2; j++)
        {
            for (int k = j + 1; k < Points.Length - 1; k++)
            {
                for (int m = k + 1; m < Points.Length; m++)
                {
                    // See if these points make a square.
                    int[] square_points =
                        GetSquarePoints(i, j, k, m);
                    if (square_points != null)
                    {
                        Solutions.Add(square_points);
                    }
                }
            }
        }
    }
}

This code simply loops through all sets of four distinct points and calls the GetSquarePoints method for the set. The GetSquarePoints method determines whether the points with the given indexes form a square and, if they do, returns an array holding the indexes in an order that forms a square. (For example, if A-B-C-D forms a square, then A-B-D-C does not.)

The picture on the right shows how the GetSquarePoints method works. Consider the point i. If this is a square, then the distances between point i and points j and m must be the same. Suppose that distance is S. Because the triangle Δikm is a 45-45-90 triangle. That means the distance between points i and m is S√2.

Knowing that little bit of geometry, you can understand the following GetSquarePoints method.

// If these points make up a square, return an array holding
// them in an order that makes a square.
// If the points don't make up a square, return null.
private int[] GetSquarePoints(int i, int j, int k, int m)
{
    // A small value for equality testing.
    const double tiny = 0.001;

    // Store all but the first index in an array.
    int[] indexes = { j, k, m };

    // Get the distances from point i to the others.
    float[] distances =
    {
        PointFDistance(Points[i], Points[j]),
        PointFDistance(Points[i], Points[k]),
        PointFDistance(Points[i], Points[m]),
    };

    // Sort the distances and the corresponding indexes.
    Array.Sort(distances, indexes);

    // If the two smaller distances are not roughly
    // the same (the side length), then this isn't a square.
    if (Math.Abs(distances[0] - distances[1]) > tiny) return null;

    // If the longer distance isn't roughly Sqr(2) times the
    // side length (the diagonal length), then this isn't a square.
    float diagonal_length = (float)(Math.Sqrt(2) * distances[0]);
    if (Math.Abs(distances[2] - diagonal_length) > tiny)
        return null;

    // See if the distance between the farther point and
    // the two closer points is roughly the side length.
    float distance1 =
        PointFDistance(Points[indexes[2]], Points[indexes[0]]);
    if (Math.Abs(distances[0] - distance1) > tiny) return null;
    float distance2 =
        PointFDistance(Points[indexes[2]], Points[indexes[1]]);
    if (Math.Abs(distances[0] - distance2) > tiny) return null;

    // It's a square!
    return new int[] { i, indexes[0], indexes[2], indexes[1] };
}

The method picks the first point arbitrarily to be point i. It calls the PointFDistance method to calculate the distances between point i and the other points. (PointFDistance is straightforward so it isn't shown here. Download the example to see how it works.)

The code then calls Array.Sort to sort the array of distances between the points. It passes an array holding the points' indexes to Array.Sort so that method can arrange the indexes so they correspond to the sorted distances. In other words, after sorting, the distance from point i to point indexes[0] is in distances[0].

Next, the code verifies that the distances to the two closer points (j and m in the picture) are the same (call it S) and that the distance to the farther point is S√2. The code finishes by determining whether the farther point (k in the picture) is distance S from the other two points.

All of these facts are consistent with a square. The only remaining question is, could there be some other points that satisfy these conditions?

Because the diagonal's length is S√2, we know that the triangles Δijk and Δimk are 45-45-90 triangles. Because those triangles share the edge i-k, the triangles are either as shown in the picture or they are the same triangle. We know they are not the same triangle because the FindSolutions method generates sets of points that do not contain duplicates so we know we have a square. (If FindSolutions created sets of four points that could contain duplicates, then you could also test that the diagonal j-m also had length S√2.)

Todd Sabuncu submitted a correct solution. Click here to download it.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in algorithms, games, mathematics | Tagged , , , , , , , , , , , | 1 Comment

Puzzle: Find the squares in C#

[puzzle]

The example Puzzle: Find the equilateral triangles in C# was fun, at least for me, so here’s another puzzle. This time your goal is find all of the squares that you can make using the red dots shown here. If you look at the solutions to the triangle puzzle, you can probably use the lessons you learn there to find the squares manually.

The trick is figuring out how to find the squares programmatically. Determining whether three points make up an equilateral triangle is fairly easy, but how do you determine whether four points make up a square?

This program has the same structure as the previous one, so all you need to do is plug in the code to find the squares. Click the Download button below to download a version of the program that is ready for you to fill in the solutions.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in algorithms, games, graphics, mathematics | Tagged , , , , , , , , , , , | 1 Comment

Save WriteableBitmap images in multiple formats in WPF and C#

[WriteableBitmap]

The post Easily save a WriteableBitmap in WPF and C# describes an extension method that makes it easy to save a WriteableBitmap object into a PNG file, but what if you want to save the image in some other format such as GIF or JPG? This example defines extension methods to allow you to do that.


The static WriteableBitmapExtensions class begins with the following enumeration that lists the available image file types.

// The available types.
public enum ImageFormats
{
    Bmp, Gif, Jpg, Png, Tif, Wmp
}

The following extension method saves a WriteableBitmap object into a file with a particular format.

// Save the WriteableBitmap into a graphic file of a given type.
public static void Save(this WriteableBitmap wbitmap,
    string filename, ImageFormats image_format)
{
    // Save the bitmap into a file.
    using (FileStream stream =
        new FileStream(filename, FileMode.Create))
    {
        BitmapEncoder encoder = null;
        switch (image_format)
        {
            case ImageFormats.Bmp:
                encoder = new BmpBitmapEncoder();
                break;
            case ImageFormats.Gif:
                encoder = new GifBitmapEncoder();
                break;
            case ImageFormats.Jpg:
                encoder = new JpegBitmapEncoder();
                break;
            case ImageFormats.Png:
                encoder = new PngBitmapEncoder();
                break;
            case ImageFormats.Tif:
                encoder = new TiffBitmapEncoder();
                break;
            case ImageFormats.Wmp:
                encoder = new WmpBitmapEncoder();
                break;
        }
        encoder.Frames.Add(BitmapFrame.Create(wbitmap));
        encoder.Save(stream);
    }
}

The method first creates a stream for the desired output file. It then declares a BitmapEncoder object. It then uses a switch statement to set that object to an instance of the appropriate encoder class for the desired image file type.

The method then creates a BitmapFrame for the WriteableBitmap and adds it to the encoder’s Frames collection. It finishes by saving the encoder’s data into the stream.

That method lets you save a WriteableBitmap into a file with a given image format, but normally the file’s extension matches the format. For example, you could (but probably wouldn’t want to) use that method to save an image in GIF format into the file names incompatible.png.

The following extension method saves a WriteableBitmap into a file with the appropriate format.

// Save the WriteableBitmap into a PNG file.
public static void Save(this WriteableBitmap wbitmap,
    string filename)
{
    FileInfo file_info = new FileInfo(filename);
    switch (file_info.Extension.ToLower())
    {
        case ".bmp":
            wbitmap.Save(filename, ImageFormats.Bmp);
            break;
        case ".gif":
            wbitmap.Save(filename, ImageFormats.Gif);
            break;
        case ".jpg":
        case ".jpeg":
            wbitmap.Save(filename, ImageFormats.Jpg);
            break;
        case ".png":
            wbitmap.Save(filename, ImageFormats.Png);
            break;
        case ".tif":
        case ".tiff":
            wbitmap.Save(filename, ImageFormats.Tif);
            break;
        case ".wmp":
            wbitmap.Save(filename, ImageFormats.Wmp);
            break;
    }
}

The method creates a FileInfo for the output file. It then uses a switch statement on the file’s extension to see what file format is appropriate. It then calls the preceding extension method to save the WriteableBitmap into the file with the correct format.

This second extension method makes saving WriteableBitmap objects really simple. The example program uses the following statements to save its image into six different files with various formats.

// Save the bitmap into different kinds of files.
wbitmap.Save("ColorSamples.bmp");
wbitmap.Save("ColorSamples.gif");
wbitmap.Save("ColorSamples.jpg");
wbitmap.Save("ColorSamples.png");
wbitmap.Save("ColorSamples.tif");
wbitmap.Save("ColorSamples.wmp");

Each of the statements saves the image with a different file format in the program’s current directory.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in extension methods, graphics, image processing, wpf, XAML | Tagged , , , , , , , , , , , , , , , , , | Leave a comment

Easily save a WriteableBitmap in WPF and C#

[WriteableBitmap]

In my post Save bitmap files in WPF and C# I lamented (okay, whined about) the cumbersomeness of saving a WriteableBitmap into a file in WPF.

Fortunately there’s a way you can make it easier. Simply add an extension method to the WriteableBitmap class that writes it into a bitmap file. The following code shows such a method.

public static class WriteableBitmapExtentions
{
    // Save the WriteableBitmap into a PNG file.
    public static void Save(this WriteableBitmap wbitmap,
        string filename)
    {
        // Save the bitmap into a file.
        using (FileStream stream =
            new FileStream(filename, FileMode.Create))
        {
            PngBitmapEncoder encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(wbitmap));
            encoder.Save(stream);
        }
    }
}

The this WriteableBitmap wbitmap part of the method declaration means this method extends the WriteableBitmap class. The parameter wbitmap represents the WriteableBitmap object for which you called the method. The second parameter, filename, is the only one that you actually pass into the method.

The method creates a FileStream to hold the saved PNG file. It creates a PngBitmapEncoder to write the file’s bitmap data. It then calls BitmapFrame.Create to create a new bitmap frame for the WriteableBitmap, and it adds the result to the encoder’s Frames collection. The code finishes by saving the encoder’s data into the FileStream.

The blue statement in the following code shows how the main program uses this method to save a WriteableBitmap into a PNG file.

// Convert the pixel data into a WriteableBitmap.
WriteableBitmap wbitmap = bm_maker.MakeBitmap(96, 96);
...
// Save the bitmap into a file.
wbitmap.Save("ColorSamples.png");

It would have been nice if Microsoft had included this functionality in the WriteableBitmap class, but at least it’s easy to add this feature with an extension method.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in extension methods, graphics, image processing, wpf, XAML | Tagged , , , , , , , , , , , , , , , | 1 Comment

Easily manipulate pixels in WPF and C#

[manipulate pixels]

After building the example Save bitmap files in WPF and C#, I couldn’t get it out of my head. Doing the math to set the correct bytes in a one-dimensional pixel array isn’t all that hard, but it is annoying and I don’t see why Microsoft had to make it so unfriendly. I thought there had to be a better way to manipulate pixels, so I decided to make it a bit friendlier.

This example defines a BitmapPixelMaker class to represent a one-dimensional array that will be used to make a WriteableBitmap object. It only supports the Bgra32 format, but you could write similar classes to handle other formats (or maybe even modify the class to handle them all).

I’ll describe the class in pieces below. The following code shows how the class starts.


// A class to represent WriteableBitmap pixels in Bgra32 format.
public class BitmapPixelMaker
{
    // The bitmap's size.
    private int Width, Height;

    // The pixel array.
    private byte[] Pixels;

    // The number of bytes per row.
    private int Stride;

    // Constructor. Width and height required.
    public BitmapPixelMaker(int width, int height)
    {
        // Save the width and height.
        Width = width;
        Height = height;

        // Create the pixel array.
        Pixels = new byte[width * height * 4];

        // Calculate the stride.
        Stride = width * 4;
    }
    ...

The class stores the bitmap’s width and height in private fields. The Pixels array will hold the bitmap’s pixel data.

Stride is the number of bytes in a row of pixel data. For the Bgra32 format, it’s just 4 bytes per pixel times the bitmap’s width.

The class’s constructor takes width and height as parameters. It allocates enough bytes for all of the pixels and calculates the stride for later use.

Most of the other methods manipulate pixels and are quite straightforward. They just do a little math to figure out where a byte needs to be in the Pixels array and then they get or set that byte. The following code shows how the class gets a pixel’s red, green, and blue values.

    // Get a pixel's value.
    public void GetPixel(int x, int y, out byte red,
        out byte green, out byte blue, out byte alpha)
    {
        int index = y * Stride + x * 4;
        blue = Pixels[index++];
        green = Pixels[index++];
        red = Pixels[index++];
        alpha = Pixels[index];
    }

The code starts by calculating the index of the first byte for this pixel. The index includes y * Stride to skip bytes used by earlier rows in the pixel data. It adds x * 4 to skip the 4 bytes for each of the pixels to the left of the target pixel in its row.

Next, the code simply copies the target pixel’s byte data into its red, green, blue, and alpha return parameters. The only thing to note here is that the Bgra32 format stores a pixel’s color components in the order: blue, green, red, alpha.

If you only need to get one color component for a pixel, the GetPixel method is a bit heavy-handed, so the class also includes methods to get the red, green, blue, and alpha components separately. For example, the following code shows the GetRed method.

    public byte GetRed(int x, int y)
    {
        return Pixels[y * Stride + x * 4 + 2];
    }

The class defines corresponding methods to manipulate pixels by setting byte values. The SetPixel method is similar to GetPixel except it sets the byte values. The class also provides methods to set the red, green, blue, and alpha components separately. For example, the following code sets the green component.

    public void SetGreen(int x, int y, byte green)
    {
        Pixels[y * Stride + x * 4 + 1] = green;
    }

The following SetColor method sets every pixel’s bytes to represent the same color

    // Set all pixels to a specific color.
    public void SetColor(byte red, byte green, byte blue,
        byte alpha)
    {
        int num_bytes = Width * Height * 4;
        int index = 0;
        while (index < num_bytes)
        {
            Pixels[index++] = blue;
            Pixels[index++] = green;
            Pixels[index++] = red;
            Pixels[index++] = alpha;
        }
    }

    // Set all pixels to a specific opaque color.
    public void SetColor(byte red, byte green, byte blue)
    {
        SetColor(red, green, blue, 255);
    }

The first version of the method simply loops through the pixel data and sets each bytes’ color data. The second version calls the first to set the pixels to the same opaque color.

The following code shows the end of the class. The MakeBitmap method converts the pixel data into a WriteableBitmap object.

    // Use the pixel data to create a WriteableBitmap.
    public WriteableBitmap MakeBitmap(double dpiX, double dpiY)
    {
        // Create the WriteableBitmap.
        WriteableBitmap wbitmap = new WriteableBitmap(
            Width, Height, dpiX, dpiY,
            PixelFormats.Bgra32, null);

        // Load the pixel data.
        Int32Rect rect = new Int32Rect(0, 0, Width, Height);
        wbitmap.WritePixels(rect, Pixels, Stride, 0);

        // Return the bitmap.
        return wbitmap;
    }
}

This method creates a new WriteableBitmap object of the correct size and dots per inch vertically and horizontally. It uses the Bgra32 format.

Next, it creates an Int32Rect to represent the part of the bitmap that should be written and uses the bitmap’s WritePixels method to write the pixel data into the bitmap. Finally the method returns the result.

The following shows part of the code that the program uses to test the BitmapPixelMaker.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    const int width = 240;
    const int height = 240;

    // Make the BitmapPixelMaker.
    BitmapPixelMaker bm_maker = new BitmapPixelMaker(width, height);

    // Clear to black.
    bm_maker.SetColor(0, 0, 0);

    ... Use BitmapPixelMaker methods to set pixel values ...

    // Convert the pixel data into a WriteableBitmap.
    WriteableBitmap wbitmap = bm_maker.MakeBitmap(96, 96);

    // Create an Image to display the bitmap.
    Image image = new Image();
    image.Stretch = Stretch.None;
    image.Margin = new Thickness(0);

    grdMain.Children.Add(image);

    // Set the Image source.
    image.Source = wbitmap;
}

The code creates a BitmapPixelMaker object and calls its SetColor method to set all of the bitmap’s pixels to black. It then uses BitmapPixelMaker methods to set pixel colors. Download the example to see how it works.

After the program has set the pixels’ values, it calls the BitmapPixelMaker object’s MakeBitmap method to create the WriteableBitmap.

The program finishes by creating an Image and displaying the WriteableBitmap in it.

The process is still a bit cumbersome, but at least the BitmapPixelMaker class makes working with the pixel data a lot easier.


Download Example   Follow me on Twitter   RSS feed   Donate




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

Display team names for a round robin tournament in C#

[round robin tournament]

The example Generate a schedule for a round robin tournament in C# explains how you can generate a schedule for a round robin tournament. This example simply adds the ability to display the schedule using the team names instead of the team numbers.

When you enter the team names and click Go, the following code executes.

// Schedule the round robin.
private void btnGo_Click(object sender, EventArgs e)
{
    // Get the teams.
    string all_teams = txtTeams.Text;
    char[] separators = { '\r', '\n' };
    string[] team_names = all_teams.Split(separators,
        StringSplitOptions.RemoveEmptyEntries);

    // Get the schedule.
    int num_teams = team_names.Length;
    int[,] results = GenerateRoundRobin(num_teams);

    // Display the result.
    string txt = "";
    for (int round = 0; round <= results.GetUpperBound(1); round++)
    {
        txt += "Round " + round + ":\r\n";
        for (int team = 0; team < num_teams; team++)
        {
            if (results[team, round] == BYE)
            {
                txt += "    " + team_names[team] + " (bye)\r\n";
            }
            else if (team < results[team, round])
            {
                txt += "    " + team_names[team] + " v " +
                    team_names[results[team, round]] + "\r\n";
            }
        }
    }

    txtResults.Text = txt;
}

The program first gets the text from the txtTeams text box. It then splits that text at carriage return and new line characters, removing any blank entries.

The program uses the length of the team_names array as the number of teams and passes it into the GenerateRoundRobin method described in the previous post.

The results array is a two-dimensional array holding team indices in its first dimension and round numbers in the second. For example, results[1, 2] is the opponent that team 1 plays in round 2 of the round robin tournament.

The code uses results.GetUpperBound(1) to get the number of rounds and loops through the rounds. For each round, the code loops through the teams and displays the matches for that round in the round robin tournament.

To avoid displaying each match twice (for example, A v B and B v A), the code only displays matches where the first team number is less than the second.

When it displays the matches, the code uses the team_names array to display the team names instead of their indices. The code that does that is highlighted in blue in the preceding code. (This is the main difference between this example and the previous one.)

You can probably find a way to use a LINQ query to display the team names, but it would probably be unnecessarily complicated and confusing. If you do find such a query, post it in a comment below.


Download Example   Follow me on Twitter   RSS feed   Donate




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

Save bitmap files in WPF and C#

[save bitmap files]

This example shows how to use WPF and C# to save bitmap files. The example Set the pixels in a WPF bitmap in C# shows how to create a WriteableBitmap in WPF. This example shows how to save the resulting bitmap.

Like many things in WPF, this is not as easy as it used to be. In a Windows Forms application, you simply call the Bitmap object’s Save method.

The following code shows how the program saves bitmap files. The code from the previous example that creates the WriteableBitmap has been omitted.


private void Window_Loaded(object sender, RoutedEventArgs e)
{
    // Make the WriteableBitmap.
    ...

    // Save the bitmap into a file.
    using (FileStream stream =
        new FileStream("ColorSamples.png", FileMode.Create))
    {
        PngBitmapEncoder encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(wbitmap));
        encoder.Save(stream);
    }

    // Tell the user we're done.
    MessageBox.Show("Done");
}

After creating the bitmap, the program creates a FileStream object associated with the file that should hold the bitmap. It creates a PngBitmapEncoder to write the object. It then calls BitmapFrame.Create to create a new bitmap frame for the WriteableBitmap, and adds the result to the encoder’s Frames collection. The code finishes by saving the encoder’s data into the FileStream.

Not very simple or intuitive, but it shouldn’t be hard to copy and paste this code when you need your program to save bitmap files.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in files, graphics, image processing | Tagged , , , , , , , , , , , , , , , | 3 Comments

Draw different styles of “illuminated” text in C#


[illuminated text]

My previous post Draw “illuminated” text in C# showed how to draw “illuminated” text. It drew each paragraph’s initial letter in a large font with a box around it.

Real illuminated manuscripts typically make the initial letter much more elaborate. They use ornate fonts and often have patterns or little pictures behind them. Sometimes they even included gold leaf and crushed gems.

You can modify the previous example to draw more interesting initial letter, but that requires you to modify the program’s code in some non-trivial ways. This example makes this process a lot easier. Its version of the DrawIlluminatedText method takes a final parameter that is a method that should be called to draw the background behind each paragraph’s initial letter. The following code shows the method’s new signature.

// Draw an illuminated paragraph.
private void DrawIlluminatedText(Graphics gr,
    float min_lead_width, float min_lead_height,
    Font lead_font, Brush lead_brush, Pen lead_pen,
    Font body_font, Brush body_brush,
    ref RectangleF rect, int paragraph_spacing, string paragraph,
    Action<Graphics, RectangleF> illuminator)
{
    ...
    // Illuminate the lead character.
    RectangleF lead_rect = new RectangleF(
        rect.X, rect.Y, lead_size.Width, lead_size.Height);
    illuminator(gr, lead_rect);

    // Draw the lead character.
    ...
}

Before the method draws the initial character, it calls this illuminator method to draw the background behind that letter.

The following code shows the simplest of this program’s three illuminator methods.

// Fill an illumination box with an image.
private void DrawIlluminationBox3(Graphics gr, RectangleF rectf)
{
    // Make the rectangle a little smaller.
    const int margin = 5;
    rectf = new RectangleF(
        rectf.X + margin, rectf.Y + margin,
        rectf.Width - 2 * margin, rectf.Height - 2 * margin);

    // Fill the rectangle with an image.
    using (Brush brush =
        new TextureBrush(Properties.Resources.Butterflies))
    {
        gr.FillRectangle(brush, rectf);
    }

    // Outline the rectangle.
    using (Pen pen = new Pen(Color.Blue, 5))
    {
        gr.DrawRectangle(pen, Rectangle.Round(rectf));
    }
}

This method creates a TextureBrush to fill areas with the image stored in the Butterflies resource and uses that brush to fill the initial character’s drawing area. It subtracts a margin from the area to allow a little extra space between the character and the paragraph’s text.

The code then outlines the area with a 5-pixel-wide blue box.

The program’s other illumination methods are a bit more complicated. Download the program to see how they work.

Now you can easily modify the illumination style by changing the illuminator method that is passed into the DrawIlluminatedText method by the main program.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in fonts, graphics, strings | Tagged , , , , , , , , , | Leave a comment