Category: utility

How to create an Alphabet bitmap in CSharp

How to create an Alphabet bitmap in CSharp

Letters generated by the programHere’s another short utility. I have been looking for a decent alphabet to look in my next game (called HogWash) . As before, I want to create a sprite sheet with letters. But every alphabet set that I found had issues with kerning. I kid you not, usually but not always with M, W, or even Q.

Even when I put together a sprite sheet manually, the editor didn’t quite get it right and letters didn’t quite fit the grid. So to simplify it, here;’s a 50 line C# program that takes the letters you supply in a string, combined with a font (Liberation Mono- from Red Hat) and a brush (black solid). It does a double loop that I exit with a goto (shock horror!) when it reaches the a terminating * in the string I supplied.

That is the graphic file above that the program below generated. As you can see the letters are far enough apart so no overlapping. Just put in your path where I have for the source and dest consts. You can use this technique for building sprite sheet.

// Author D. Bolton Learncgames.com You are free to use and copy this program as you wish but please leave this line in.
using System;
using System.Drawing;
using System.Drawing.Imaging;

namespace buildfont
{
    class Program
    {
        const int LetterWidth = 100;
        const int LetterHeight = 120;
        const string source = "Your path"
        const string dest = @"YourPath\letters.png";

        static Bitmap allLetters = new Bitmap(LetterWidth * 8,LetterHeight * 5);

        static void Main(string[] args)
        {
            BuildOneImage();
        }

        private static void BuildOneImage()
        {
            var font = new Font("Liberation Mono",95);
            var brush = new SolidBrush(Color.Black);
            var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ*";
            Console.WriteLine("Creating letters.png");
            var aty = 0.0f;
            using (Graphics g = Graphics.FromImage(allLetters))
            {
                var strindex = 0;
                for (var y = 0; y < 5; y++)
                {
                    var atx = 0.0f;
                    for (int x = 0; x < 6; x++)
                    {
                        string aLetter = str[strindex++].ToString();
                        if (aLetter == "*") goto Done;
                        g.DrawString(aLetter, font, brush, atx, aty);
                        atx += LetterWidth;
                    }
                    aty += LetterHeight;
                }
            }
            Done:
            allLetters.Save(dest, ImageFormat.Png);
        }
    }
}
How to create a big image from a number of smaller ones

How to create a big image from a number of smaller ones

Card DeckAfter the day before yesterday’s experiment showed that loading a single larger image on an Android phone is nearly three times faster than loading 52 smaller images, I decided to write a short utility program to read all the 52 individual card files and create one file with them laid out neatly in four rows of cards, one row per suite with each card running from Ace to King.

The individual card .png files were all in one folder with two letter filenames rank and suit in capitals like AS.png (Ace of spades), TH.png (Ten of Hearts and so on).

This 62 line C# program reads all 52 files into RAM in a two-dimension array cards (original name eh!) in the method LoadAllImages() then in BuildOneImage() it writes them out in the four rows into the bitmap allcards then saves them out as one .png format file.

C# makes doing this very easy. In C you would have to write your own file format handling code or use a library like libpng.

// Author D. Bolton Learncgames.com You are free to use and copy this program as you wish but please leave this line in.
using System;
using System.Drawing;
using System.Drawing.Imaging;

namespace mpics
{
    class Program
    {
        const int CardWidth = 100;
        const int CardHeight = 153;
        const string source = "your path here"; // Path to all 52 card files
        const string dest = "target file here"; // Path + filename for target .png file.
        const string suits = "HCDS";
        const string ranks = "A23456789TJQK";

        static Bitmap[,] cards = new Bitmap[13,4];
        static Bitmap allcards = new Bitmap(CardWidth * 13,CardHeight * 4);

        static void Main(string[] args)
        {
            LoadAllImages();
            BuildOneImage();
        }

        private static void BuildOneImage()
        {
            Console.WriteLine();
            var aty = 0.0f;
            using (Graphics g = Graphics.FromImage(allcards))
            {
                for (var y = 0; y < 4; y++)
                {
                    var atx = 0.0f;
                    for (int x = 0; x < 13; x++)
                    {
                        var r = new Rectangle((int)atx, (int)aty, CardWidth, CardHeight);
                        g.DrawImage(cards[x,y],r);
                        atx += CardWidth;
                    }
                    aty += CardHeight;
                }
            }
            allcards.Save(dest, ImageFormat.Png);
        }

        private static void LoadAllImages()
        {
            var i = 0;
            foreach (char c in suits)
            {
                var j = 0;
                foreach (char r in ranks)
                {
                    var s = source + r + c+".png";
                    cards[j++,i] = (Bitmap)Bitmap.FromFile(s);
                }
                i++;
            }
        }
    }
}

Don’t forget to set the source and dest path constants. This was compiled in Visual Studio 2019 and run on Windows 10. The only really important thing I found was using the Rectangle r in BuildOneImage(). If I used just atx and aty and didn’t specify the size of card then DrawImage() drew much smaller images into the bitmap. I’m not sure why as the card images when loaded from disk were 100 wide by 153 deep, the same as specified in the constants CardWidth and CardHeight.

The card images were originally downloaded from the American Contract Bridge League but were much bigger so I scaled them first to 100 x 153 pixels. There are many free playing card images on the web but these are one of the nicer sets.