Page 1 of 1

Signature Maker Tutorial (Build an Application)

#1 RexGrammer  Icon User is offline

  • Coding Dynamo
  • member icon

Reputation: 182
  • View blog
  • Posts: 783
  • Joined: 27-October 11

Posted 19 December 2011 - 09:18 AM

Signature Maker Tutorial


So I recently came by Martyr2's HUGE list of ideas, and I decided to realize one of them! ;)

You can see it Here! And whenever you need an idea you should search through it!

I traversed through the Graphics section and, thought that the 'Signature Maker' would be a great project.

When I made it I thought it would be a great tutorial.

A 5min brainstorm and I got the skeleton idea of the project planned:

1. The user can select a background
2. And then add some text to it
3. He can also select the font, color and position of the text
4. He can save in many formats

OK! Let's design the form!

Posted Image

NOTE: The 'empty' space is actually a pictureBox

I did it like this but if you want yo do it in any other way (feel free to)

The problem now emerges: How to list all of the available backgrounds?
We could make a folder and store all images there...

Get Images Path Feature


Let's create a method that returns a list of strings and accepts the folder name as a parameter!

public List<String> GetImagesPath(string folderToSearch)
        {
        }



Now we want to add a using directive for System.IO:

using System.IO;



Now what we want to do is to get the directory info for the inputted folder. There is a class in System.IO that does just that it's called DirectoryInfo

Find more info on it here: DirectoryInfo Class (MSDN Article)

Now to declare and initialize a new DirectoryInfo instance:

The constructor for DirectoryInfo accepts only one parameter, the file path.
DirectoryInfo folder = new DirectoryInfo(folderToSearch);



Now we want to get info on the files there. Again System.IO comes to the rescue with it's FileInfo class.

Find more info on it here: DirectoryInfo Class (MSDN Article)

Now declare a fileinfo array called images and initialize it to the files in the folder specified.

FileInfo[] images = folder.GetFiles();



Now declare a list of strings that will hold the file paths:

List<string> imagesList = new List<String>();



Now we want to iterate through all of the files in the fileinfo and add each one's path to the list:

 for (int i = 0; i < images.Length; i++)
            {
                imagesList.Add(String.Format(@"{0}/{1}", folderToSearch, images[i].Name));
            }



And then return the list of images:

return imagesList;



Now we can easily load the files in the list box. Let's create a method for that too. To make it re-usable we will make it add the files to a listBox that will be passed as a parameter.

private void LoadImages(ListBox list, string folder)
        {
        }



So we want to do the same for each of the strings in the list, that is to add the file name to the list box.

We can do it like this:

foreach (string image in GetImagesPath(folder))
            {
                listBox.Items.Add(Path.GetFileNameWithoutExtension(image));
            }



We are calling the method we created passing the folder as the parameter

NOTE: I'm using the Path class of the System.IO namespace to get the actual file names not paths

Some info on the path class: Path Class (MSDN Article)

Now call that method in the mainForm_Load event:

LoadImages(backgroundsList, "BackGround Images");



We've finished the getting of the backgrounds. Congrats!

Saving Feature


We'll do the save feature now. Let's create a method for that too! :D

The method will accept the image to save the path and the format as the parameters

private void SaveImage(Image image, string path, ImageFormat format)
        {
        }



For the actualy saving we want to use a stream to save the image in a specific format.

using (Stream stream = new FileStream(path, FileMode.Create))
                image.Save(stream, format);



NOTE: The FileMode.Create states that a new file will be created or a old one will be overwritten!

The Save() method of the image accepts the stream and the format as parameters...

Now make the saveFileDialog's filter property to:
Bitmap Image (*.bmp)|*.bmp|GIF Image (*.gif)|*.gif|PNG Image (*.png)|*.png|Tiff Image (*.tiff)|*.tiff|JPEG Image (*.jpg)|*.jpg



This will show these formats in the format box of the saveFileDialog...

Now for the saveBtn event handler...

When the user clicks the save button we want to show a dialog and 'catch' the result:

DialogResult res = saveFileDialog.ShowDialog();



If the user clicked 'OK':

if (res == DialogResult.OK)
            {
            }



Get the extension specified:
string extension = Path.GetExtension(saveFileDialog.FileName);



And then check it for the available format's and save in the correct one:

                if (extension == ".bmp")
                    SaveImage(previewBox.BackgroundImage, saveFileDialog.FileName, ImageFormat.Bmp);
                else if (extension == ".gif")
                    SaveImage(previewBox.BackgroundImage, saveFileDialog.FileName, ImageFormat.Gif);
                else if (extension == ".png")
                    SaveImage(previewBox.BackgroundImage, saveFileDialog.FileName, ImageFormat.Png);
                else if (extension == ".tiff")
                    SaveImage(previewBox.BackgroundImage, saveFileDialog.FileName, ImageFormat.Tiff);
                else if (extension == ".jpg")
                    SaveImage(previewBox.BackgroundImage, saveFileDialog.FileName, ImageFormat.Jpeg);



Exit Feature


:D :
Close();


:D

Only-Numbers-And-Backspace-Textbox Feature


Let's create a custom event handler that will handle the both of the location textBoxes KeyPress event. It will accept the sender and the KeyPressEventArgs as the parameters.

private void location_KeyPress(object sender, KeyPressEventArgs e)
        {
        }



Now let's make the user only allowed to input a number or the backspace by making the textBox 'handle' (dump) all other keys:
e.Handled = !(Char.IsNumber(e.KeyChar) || e.KeyChar == 8);



Now link this event handler to the KeyPress event of both textBoxes:

Posted Image

Setting The Background


Let's do this in the selected index changed event of the listBox (to create it just double-click the listBox)...

We want firstly to set the picture box's background image accordingly (that is to the index selected):

I done it like this:
previewBox.BackgroundImage = Image.FromFile(GetImagesPath("BackGround Images")[backgroundsList.SelectedIndex]);



Now make both of the bottom textBoxes enabled property to false

And then show the size of that image in the appropriate text boxes:

imageX.Text = previewBox.BackgroundImage.Width.ToString();
imageY.Text = previewBox.BackgroundImage.Height.ToString();



Color & Font Features


These ones are easy.

Show the appropriate dialog in the appropriate button click and set the appropriate property of the textBox:

fontDialog.ShowDialog();
imageText.Font = fontDialog.Font;



colorDialog.ShowDialog();
imageText.ForeColor = colorDialog.Color;



NOTE: You don't need to check if the user clicked OK due to the nature of these two dialogs

Updating the Signature


Create a method that accepts the image to update, the text to input, the font for text, the brush (representing the color) of the text and the x and y locations, and that returns a Image (the updated one)

private Image UpdateSignature(Image image, string text, Font font, Brush brush, int x, int y)
        {
        }



Now create graphics on the inputted image:

Graphics g = Graphics.FromImage(image);



And then draw the text with the proper formatting:

g.DrawString(text, font, brush, x, y);



And then return the updated image:

return image;



Now to write the event handler for the updateBtn_Click event:

We want to check if there is some input in each textBox:

if (!string.IsNullOrEmpty(imageText.Text))
            {
                if (!string.IsNullOrEmpty(textLocationX.Text))
                {
                    if (!string.IsNullOrEmpty(textLocationY.Text))
                    {
                    }
                }
            }



NOTE: I opted to do nested if's rather than doing all of that in one if with the 'and' logical operation on these bools (&&)

Check if the user inputted sizes are larger than the actual image size, if they are show a message to the user:

if (int.Parse(textLocationX.Text) > previewBox.BackgroundImage.Width || int.Parse(textLocationY.Text) > previewBox.BackgroundImage.Height)
                            MessageBox.Show("Please input the tex box location within the image size.");



If not then 'collect' all of the input:

else
{
                            string textToUpdate = imageText.Text;
                            Font fontToUpdate = imageText.Font;
                            SolidBrush brushToUpdate = new SolidBrush(imageText.ForeColor);
                            int locationX = int.Parse(textLocationX.Text);
                            int locationY = int.Parse(textLocationY.Text);
}



NOTE: no need to check if the textBox inputs can be parsed because we restricted the user to input only numbers

Reset the background picture of the picture box (to the selected background):

We do this because we don't want multiple text's drawn onto the pictureBox

previewBox.BackgroundImage = Image.FromFile(GetImagesPath("BackGround Images")[backgroundsList.SelectedIndex]);



And finally update the picturebox background image with the method we created, passing all of the appropriate (collected) parameters:

previewBox.BackgroundImage = UpdateSignature(previewBox.BackgroundImage, textToUpdate, fontToUpdate, brushToUpdate, locationX, locationY);



That wraps it up! This was a quick tutorial focusing on some graphics functions and some general programming 'tricks'.

You can always check out the newest version of the program at my GitHub Repo

Direct download of the solution from GitHub: here!

This post has been edited by RexGrammer: 17 January 2012 - 12:32 PM


Is This A Good Question/Topic? 0
  • +

Page 1 of 1