Title: Verify sizes of playing cards in C#
Recently I wanted to use some playing cards in a program so I looked online for some nice images. I could have included 55 or so separate images (including jokers and backs), but I decided it would be easier to use a single image to hold images for all of the playing cards.
Surprisingly when I tried to display the playing cards, the images didn't line up. The first few cards looked okay but then later cards lined up more and more badly until the last few didn't fit at all.
If you look closely at the red outlines in the picture on the right, you'll see that the Ace of hearts lines up nicely but the cards on the bottom and right edges of the picture do not sit well within their outlines.
The problem is that the image of the playing cards doesn't give each card an integral size. I suspect what happened in these cases is that the image's author made the playing cards at a handy size and then scaled the image of the deck to some other size that was convenient for posting. For example, the image shown here that doesn't line up nicely was originally 994×447 pixels in size. (It's included in the download so you can see it and you can find it on Wikimedia Commons.)
The width 994 divided by 13 is 76.46, so the cards don't have integral widths. The program truncates the result to 76. As it moves to the right through the image of the deck, the missing 0.46 adds up until the final cards are pretty far out of alignment. (The same thing happens vertically.)
One solution (and the one I probably should have taken because it would have been easier) would be to use the float data type for the card dimensions. I decided that I wanted to use integer dimensions so the card images wouldn't be scaled and they would be perfect.
Eventually I found an image online (at thehouseofcards.com) with dimensions 936×500. It has 13 columns and 5 rows of playing cards so each is exactly 72×100 pixels.
Anyway, I wrote this program to load an image containing playing cards and then draw lines to show how the cards line up.
When it starts, the program uses the following code to save the original image of the playing cards.
// The original image.
private Bitmap OriginalImage = null;
// Save the original image.
private void Form1_Load(object sender, EventArgs e)
{
OriginalImage = picDeck.Image as Bitmap;
}
When you click the Outline button, the following code executes.
// Draw lines on the deck to show where the cards are.
private void btnOutline_Click(object sender, EventArgs e)
{
int NumSuits = int.Parse(txtNumSuits.Text);
int NumRanks = int.Parse(txtNumRanks.Text);
Bitmap bm = new Bitmap(picDeck.Image);
using (Graphics gr = Graphics.FromImage(bm))
{
int wid = bm.Width / NumRanks;
int hgt = bm.Height / NumSuits;
for (int x = 0; x <= NumRanks; x++)
gr.DrawLine(Pens.Blue, x * wid, 0, x * wid, bm.Height);
for (int y = 0; y <= NumSuits; y++)
gr.DrawLine(Pens.Blue, 0, y * hgt, bm.Width, y * hgt);
}
picDeck.Image = bm;
}
This code parses the number of suits and ranks that you entered in the form's text boxes. It then creates a new Bitmap that contains a copy of the original image, and then makes an associated Graphics object.
Next the code calculates the integral dimensions of the individual playing cards. It loops through the ranks drawing vertical lines between the cards and then loops through the suits drawing horizontal lines between the cards.
Finally the code displays the new image.
In my next post, I'll describe a program that uses this image to load the separate playing cards. It then displays them in a way that lets the program figure out which card is displayed where.
Download the example to experiment with it and to see additional details.
|