示例#1
0
        /// <summary>
        /// Populates the _flowLayoutPanel with images from the directory selected in the
        /// _folderBrowserDialog.  This method is designed to be called on a background thread.
        /// </summary>
        private void PopulateImages()
        {
            //TODO: Support ".jpeg" also?  Can I do that with a comma or some other syntax e.g. *.jpg,*.jpeg ?
            string[] filenames = System.IO.Directory.GetFiles(this._folderBrowserDialog.SelectedPath, "*.jpg");

            //Set the current directory that we'll use to load and save files
            System.IO.Directory.SetCurrentDirectory(this._folderBrowserDialog.SelectedPath);

            //Inform the progress dialog of the count of files that we'll be loading.  (This is needed by
            //the progress dialog to calculate the percentage finished based on the number of the current
            //file being processed.)
            Invoke(this._setProgressDialogFileCount, new object[] { filenames.Length });

            //Build the list of images that we'll display in the dialog.
            List <string> errorFiles = new List <string>();
            int           imageIndex = 1;

            foreach (string filename in filenames)
            {
                //Skip loading the remainder of the files if the Cancel button on the progress meter was clicked.
                if (this._cancelOperation == true)
                {
                    break;
                }

                //Update the Loading dialog with the number of files loaded so far.
                Invoke(this._updateProgressDialog, new object[] { imageIndex });

                //The height and width of the maximum allowed size of thumbnail images.
                const int maxThumbnailHeightWidth = 140;
                const int borderWidth             = 6;

                DualImagePanel innerPanel = new DualImagePanel(maxThumbnailHeightWidth, maxThumbnailHeightWidth);
                innerPanel.Width          = 335;
                innerPanel.Height         = 170;
                innerPanel.Location       = new Point(borderWidth, borderWidth);
                innerPanel.BackColor      = this.BackColor;
                innerPanel.RotationEvent += new DualImagePanel.RotationDelegate(innerPanel_RotationEvent);

                //Get the image from the file, create a small (thumbnail) version of the image
                //that will fit within the containing panel, and put the thumbnail image into
                //the panel.  Then release the original image.  (For lots of large images, it
                //would take too much memory to hold all of the originals in memory.)
                try
                {
                    //NOTE: Using Image.FromStream() instead of Image.FromFile() to load images, it is *much* faster!
                    //Thanks to http://www.shahine.com/omar/CommentView,guid,673c131f-26db-4f44-9908-c2667da832ad.aspx
                    using (FileStream fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read))
                    {
                        using (Image image = Image.FromStream(fileStream, true, false))
                        {
                            Image thumbnailImage = Utility.ResizeImageToFitRectangle(image, new Size(maxThumbnailHeightWidth, maxThumbnailHeightWidth));

                            Orientation imageOrientation = Utility.GetImageOrientation(image);
                            innerPanel.SetOriginalImage(thumbnailImage, imageOrientation, filename);
                        }
                    }
                    this._imageCount++;
                }
                catch (Exception)
                {
                    //Note: I've seen an OutOfMemory exception get thrown when trying to read a file with
                    //an extension of .jpg, but that isn't really an image file.  Regardless of what went
                    //wrong, just skip the file and go on to the next one.
                    errorFiles.Add(filename);
                    continue;
                }

                //For computers with low memory and large pictures: release memory now
                GC.Collect();

                //Add the innerPanel to the form.
                object[] controlArguments = new object[] { innerPanel };
                this.Invoke(this._addItemToFlowLayoutPanel, controlArguments);

                if (innerPanel.Orientation != Orientation.Initial)
                {
                    this._rotatedImageCount++;
                }

                imageIndex++;
            }

            //If there were any images that we couldn't load successfully, display an error message
            //with the name(s) of the files that failed to load.
            if (errorFiles.Count > 0)
            {
                string errorMessage = "Error: " + errorFiles.Count + " file(s) did not load correctly and were skipped:" + Environment.NewLine + Environment.NewLine;
                errorMessage += errorFiles[0];
                for (int fileIndex = 1; fileIndex < errorFiles.Count; fileIndex++)
                {
                    //Show a max of 50 failed filenames
                    if (fileIndex > 50)
                    {
                        errorMessage += ", ...";
                        break;
                    }

                    errorMessage += ", " + errorFiles[fileIndex];
                }
                MessageBox.Show(errorMessage, Utility.APP_NAME, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

            //Update the status bar text and close the progress dialog.
            this.Invoke(this._updateStatusText);
            this.Invoke(this._operationFinished);
        }
示例#2
0
 /// <summary>
 /// Activated by the background thread when the rotated image for the specified panel has
 /// been saved to disk, replacing the original image on disk.  On the specified DualImagePanel,
 /// sets the original image to be the rotated image, and sets the orientation to Initial.
 /// </summary>
 private void SetRotatedImageAsOriginalImage(DualImagePanel panel)
 {
     panel.SetRotatedImageAsOriginalImage();
 }