/// <summary> /// Event handler method for the DragDrop action, performs validation and imports image properties into program. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MainForm_DragDrop(object sender, DragEventArgs e) { // Create a string array that contains complete file paths to the imported files string[] itemArray = (string[])e.Data.GetData(DataFormats.FileDrop); // Validate the imported items with the AreAllImageFiles method if (Validation.AreAllImageFiles(itemArray)) { // If the array is successfully validated, try to clear any existing items in the // ListView and ImageObjectList and then populate them with new values try { Logic.ClearItemsFromObjectList(ImageObjectList); View.ClearItemsFromListView(lvItemList); Logic.PopulateImageObjectList(itemArray, ImageObjectList); View.PopulateListView(ImageObjectList, lvItemList); } catch (ArgumentException) { // Display an 'unexpected error' MessageBox when an ArgumentException is thrown PresetMessageBox.UnexpectedError(""); } } else { // Display a 'File Type Error' MessageBox when the array is not validated successfully PresetMessageBox.FileTypeError(); } }
/// <summary> /// Event handler method for the 'Delete Selected' button click action, performs validation and deletes selected items from ListView and ImageObjectList. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BtnDeleteSelected_Click(object sender, EventArgs e) { // Validate the selection of at least one item if (Validation.AtLeastOneItemIsSelected(lvItemList)) { // Loop through each item in the ListView SelectedItems collection and // attempt to remove them form the ListView and ImageObjectList using the current item's index foreach (ListViewItem item in lvItemList.SelectedItems) { try { int index = item.Index; // Remove item(s) from ListView and ImageObjectList by index View.RemoveItemFromListViewByIndex(lvItemList, index); Logic.RemoveItemFromObjectListByIndex(ImageObjectList, index); } catch (NullReferenceException) { // Display an 'Unexpected Error' MessageBox when a NullReferenceException is thrown, then clear all items from the ImageObjectList and ListView PresetMessageBox.UnexpectedError("All imported images will be wiped from memory to ensure stability."); View.ClearItemsFromListView(lvItemList); Logic.ClearItemsFromObjectList(ImageObjectList); } } } else { // If nothing is selected, display a 'Nothing Selected' MessageBox PresetMessageBox.NothingSelectedError(); } }
/// <summary> /// Event handler method for the 'Process Images' button click action, performs validation and opens ConfirmForm /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BtnProcessImages_Click(object sender, EventArgs e) { // Validate the existence of items in the ListView if (Validation.ListViewContainsAtLeastOneItem(lvItemList)) { // If ListView contains at least one item, show the ConfirmDialog new ConfirmForm(ImageObjectList, lvItemList).ShowDialog(); } else { // Display an 'Empty List' MessageBox when there aren't any items in the list PresetMessageBox.EmptyListError(); } }
/// <summary> /// Event handler method for the 'Clear List' button click action, performs validation and clears the ListView and ImageObjectList of ImageObjects. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BtnClearList_Click(object sender, EventArgs e) { // Validate the existence of items in the ListView if (Validation.ListViewContainsAtLeastOneItem(lvItemList)) { // If at least one item exists in the list, clear all ImageObject Objects from ImageObjectList and all items from the ListView Logic.ClearItemsFromObjectList(ImageObjectList); View.ClearItemsFromListView(lvItemList); } else { // Display an 'Empty List' MessageBox when there aren't any items in the list PresetMessageBox.EmptyListError(); } }
/// <summary> /// Event handler method for the 'Process Images' button click action, performs validation and opens ConfirmForm /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BtnImportImages_Click(object sender, EventArgs e) { // Initialize an OpenFileDialog object to let user select files using (OpenFileDialog importImagesDialog = new OpenFileDialog()) { // Set the MultiSelect property of OpenFileDialog to true to allow selecting multiple images in one import importImagesDialog.Multiselect = true; // Show dialog and check if the result is 'OK' if (importImagesDialog.ShowDialog() == DialogResult.OK) { // Create a string array that contains complete file paths to the imported files selected in OpenFileDialog string[] itemsFilePaths = importImagesDialog.FileNames; // Validate the imported items with the AreAllImageFiles method if (Validation.AreAllImageFiles(itemsFilePaths)) { try { // If the array is successfully validated, try to clear any existing items in the // ListView and ImageObjectList and then populate them with new values Logic.ClearItemsFromObjectList(ImageObjectList); View.ClearItemsFromListView(lvItemList); Logic.PopulateImageObjectList(itemsFilePaths, ImageObjectList); View.PopulateListView(ImageObjectList, lvItemList); } catch (ArgumentException) { // Display an 'unexpected error' MessageBox when an ArgumentException is thrown PresetMessageBox.UnexpectedError(""); } } else { // Display a 'File Type Error' MessageBox when the array is not validated successfully PresetMessageBox.FileTypeError(); } } } }
/// <summary> /// Pad image with whitespace and re-size it to specified dimensions, then save it to specified destination. /// </summary> /// <param name="Image"></param> /// <param name="size"></param> /// <param name="destination"></param> public static void ProcessImage(ImageObject Image, int size, string destination) { try { using (Bitmap BitmapImage = new Bitmap(Image.FileLocation)) { // Initialize variables int sourceWidth = BitmapImage.Width; int sourceHeight = BitmapImage.Height; int sourceX = 0; int sourceY = 0; int destX = 0; int destY = 0; float nPercent = 0; float nPercentW = 0; float nPercentH = 0; // Calculate the percentage source Width of the image compared to the desired Width nPercentW = ((float)size / sourceWidth); // Calculate the percentage source Height of the image compared to the desired Height nPercentH = ((float)size / sourceHeight); // Test which dimension percentage is smaller if (nPercentH < nPercentW) { // Assign smaller dimension percentage to nPercent nPercent = nPercentH; // If the smaller dimension is height, calculate how many pixels the image has to be shifted down to center it // Then, assign the value to the destX variable destX = Convert.ToInt16((size - (sourceWidth * nPercent)) / 2); } else { // Assign smaller dimension percentage to nPercent nPercent = nPercentW; // If the smaller dimension is width, calculate how many pixels the image has to be shifted to the right to center it // Then, assign the value to the destY variable destY = Convert.ToInt16((size - (sourceHeight * nPercent)) / 2); } // Calculate and assign the destination width and height of the original image inside the desired size Bitmap int destWidth = (int)(sourceWidth * nPercent); int destHeight = (int)(sourceHeight * nPercent); // Initialise imageEncoder object from GetImageEncoders method // Later the JPEG encoder is taken from this object to save the image with ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders(); // Initialize encoderParameters with highest quality possible and save the image using this encoder EncoderParameters encoderParameters = new EncoderParameters(1); encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 100L); // Create blank bitmap to draw to with the specified destination size using (Bitmap bmPhoto = new Bitmap(size, size, PixelFormat.Format24bppRgb)) { // Set resolution of Bitmap equal to the source resolution of original image bmPhoto.SetResolution(BitmapImage.VerticalResolution, BitmapImage.HorizontalResolution); // Initilialise graphics object that will be used to draw the final image using (Graphics grPhoto = Graphics.FromImage(bmPhoto)) { // Clear the image and set the background color to white grPhoto.Clear(Color.White); // Specify graphics object properties for highest quality Image manipulation grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic; grPhoto.SmoothingMode = SmoothingMode.HighQuality; grPhoto.PixelOffsetMode = PixelOffsetMode.HighQuality; grPhoto.CompositingQuality = CompositingQuality.HighQuality; // Draw original image onto the Graphics, offset by either height or width co-ordinates grPhoto.DrawImage(BitmapImage, new Rectangle(destX, destY, destWidth, destHeight), new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), GraphicsUnit.Pixel); // Save the manipulated Bitmap to the specified destination with the Jpeg encoder, with highest quality encoder parameters bmPhoto.Save(destination + "\\" + Image.FileName, imageEncoders[1], encoderParameters); } } } } catch (OutOfMemoryException) { // Catch an OOM exception if the created Bitmap is too large for the system, then gracefully exit the program. PresetMessageBox.OutOfMemoryError(); Application.Exit(); } }
/// <summary> /// Event handler method for the 'Start' button click action, performs validation and processes images, then saves them. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BtnStart_Click(object sender, EventArgs e) { // Assign a true or false value to a variable that's evaluated to check if size textBoxes can be parsed as integers bool successfullyParsed = int.TryParse(tbTargetSizeMain.Text, out int mainSize); successfullyParsed = int.TryParse(tbTargetSizeThumb.Text, out int thumbNailSize); // If both size textBoxes values can be parsed as integers, go forward if (successfullyParsed) { // Initialize strings for mainDestination and thumbDestination directories, and a counter variable string mainDestination = tbDestinationMain.Text; string thumbDestination = tbDestinationThumb.Text; int i = 0; // Test if all textBoxes have a value if (Validation.IsNotEmpty(mainSize) && Validation.IsNotEmpty(thumbNailSize) && Validation.IsNotEmpty(mainDestination) && Validation.IsNotEmpty(thumbDestination)) { // Initialize a string variable that will hold the returned validation message. For readability reasons. string validationMessage = Validation.AreValidDirectories(mainDestination, thumbDestination); // If AreValidDirectories returns the string "valid", go forward if (validationMessage == "valid") { // Loop through each ImageObject Object in ImageObjectList and attempt to call ProcessImage for each one. foreach (ImageObject Image in ImageObjectList) { try { // Attempt to process each ImageObject Logic.ProcessImage(Image, mainSize, mainDestination); Logic.ProcessImage(Image, thumbNailSize, thumbDestination); } catch (ArgumentException) { // If ArgumentException is thrown, show which file caused the issue and continue with next image. PresetMessageBox.ErrorWithFile(Image.FileLocation, Image.FileName); continue; } // Increment the counter, update the "Images Processed" counter label, then refresh the label after each image is processed i++; lblProcessed.Text = "Images Processed : " + i; lblProcessed.Refresh(); } // Once all possible images are processed, clear the ListView and ImageObjectList of items and display a "Processing Finished" MessageBox Logic.ClearItemsFromObjectList(ImageObjectList); View.ClearItemsFromListView(lvItemList); PresetMessageBox.ProcessingFinished(); // Close the form once all possible images are processed ActiveForm.Close(); } // If there is an issue with the supplied directories, AreValidDirectories will return a string with more details that's passed to the DirectoryError MessageBox else { PresetMessageBox.DirectoryError(validationMessage); } } // If one or more TextBoxes have a missing value, display the "Missing Parameters" MessageBox else { PresetMessageBox.MissingParametersError(); } } // If the size TextBoxes couldn't be parsed, display a "Parameter Error" MessageBox else { PresetMessageBox.ParameterError(); } }