using System; using System.Drawing; using System.Collections; using System.Collections.Specialized; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.IO; using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Xml; using System.Xml.XPath; namespace eBay_Images { /// /// Summary description for ImageResize. /// public class ImageResize : System.Windows.Forms.Form { private System.Windows.Forms.Button LoadImage; private System.Windows.Forms.OpenFileDialog openFileDialog1; private System.Windows.Forms.PictureBox PictureBox1; private System.Windows.Forms.HScrollBar CropX; private System.Windows.Forms.VScrollBar CropY; private System.Windows.Forms.VScrollBar CropHeight; private System.Windows.Forms.HScrollBar CropWidth; private System.Windows.Forms.Button UploadImage; private System.Windows.Forms.ListBox ListImages; private System.Windows.Forms.Label ListImagesLabel; private System.Windows.Forms.Button GenerateHTML; private System.Windows.Forms.Button ClearImages; private System.Windows.Forms.ToolTip ImageToolTip; private Button btnListMoveUp; private Button btnListDelete; private Button btnListMoveDown; private Button btnImageRotateRight; private Button btnImageRotateLeft; private System.ComponentModel.IContainer components; public ImageResize() { // // Required for Windows Form Designer support // InitializeComponent(); // Setup "About" application context menu entry IntPtr SystemMenu = User32.GetSystemMenu(this.Handle, false); User32.AppendMenu(SystemMenu, User32.MenuFlags.MF_SEPARATOR, 0, ""); User32.AppendMenu(SystemMenu, User32.MenuFlags.MF_STRING, 0x200, "About"); // Fix rotate left button to mirror the rotate right button's icon. var rotateLeft = this.btnImageRotateLeft.Image; rotateLeft.RotateFlip(RotateFlipType.Rotate180FlipY); } /// /// Clean up any resources being used. /// protected override void Dispose(bool disposing) { if (disposing) { if (components != null) { components.Dispose(); } } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ImageResize)); this.LoadImage = new System.Windows.Forms.Button(); this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); this.PictureBox1 = new System.Windows.Forms.PictureBox(); this.CropY = new System.Windows.Forms.VScrollBar(); this.CropHeight = new System.Windows.Forms.VScrollBar(); this.CropWidth = new System.Windows.Forms.HScrollBar(); this.CropX = new System.Windows.Forms.HScrollBar(); this.UploadImage = new System.Windows.Forms.Button(); this.ListImages = new System.Windows.Forms.ListBox(); this.ListImagesLabel = new System.Windows.Forms.Label(); this.GenerateHTML = new System.Windows.Forms.Button(); this.ClearImages = new System.Windows.Forms.Button(); this.ImageToolTip = new System.Windows.Forms.ToolTip(this.components); this.btnListMoveUp = new System.Windows.Forms.Button(); this.btnListDelete = new System.Windows.Forms.Button(); this.btnListMoveDown = new System.Windows.Forms.Button(); this.btnImageRotateLeft = new System.Windows.Forms.Button(); this.btnImageRotateRight = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.PictureBox1)).BeginInit(); this.SuspendLayout(); // // LoadImage // this.LoadImage.Anchor = System.Windows.Forms.AnchorStyles.Bottom; this.LoadImage.Location = new System.Drawing.Point(88, 210); this.LoadImage.Name = "LoadImage"; this.LoadImage.Size = new System.Drawing.Size(104, 23); this.LoadImage.TabIndex = 0; this.LoadImage.TabStop = false; this.LoadImage.Text = "Load Image..."; this.LoadImage.Click += new System.EventHandler(this.LoadImage_Click); // // openFileDialog1 // this.openFileDialog1.DefaultExt = "jpg"; this.openFileDialog1.Filter = "JPEG Images|*.jpg"; this.openFileDialog1.Title = "Choose an Image..."; // // PictureBox1 // this.PictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.PictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.PictureBox1.Location = new System.Drawing.Point(35, 24); this.PictureBox1.Name = "PictureBox1"; this.PictureBox1.Size = new System.Drawing.Size(206, 158); this.PictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; this.PictureBox1.TabIndex = 2; this.PictureBox1.TabStop = false; // // CropY // this.CropY.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left))); this.CropY.LargeChange = 1; this.CropY.Location = new System.Drawing.Point(19, 24); this.CropY.Name = "CropY"; this.CropY.Size = new System.Drawing.Size(16, 158); this.CropY.TabIndex = 1; this.CropY.Scroll += new System.Windows.Forms.ScrollEventHandler(this.CropY_Scroll); // // CropHeight // this.CropHeight.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Right))); this.CropHeight.LargeChange = 1; this.CropHeight.Location = new System.Drawing.Point(241, 24); this.CropHeight.Name = "CropHeight"; this.CropHeight.Size = new System.Drawing.Size(16, 158); this.CropHeight.TabIndex = 3; this.CropHeight.Scroll += new System.Windows.Forms.ScrollEventHandler(this.CropHeight_Scroll); // // CropWidth // this.CropWidth.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.CropWidth.LargeChange = 1; this.CropWidth.Location = new System.Drawing.Point(35, 182); this.CropWidth.Name = "CropWidth"; this.CropWidth.Size = new System.Drawing.Size(206, 16); this.CropWidth.TabIndex = 4; this.CropWidth.Scroll += new System.Windows.Forms.ScrollEventHandler(this.CropWidth_Scroll); // // CropX // this.CropX.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.CropX.LargeChange = 1; this.CropX.Location = new System.Drawing.Point(35, 8); this.CropX.Name = "CropX"; this.CropX.Size = new System.Drawing.Size(206, 16); this.CropX.TabIndex = 2; this.CropX.Scroll += new System.Windows.Forms.ScrollEventHandler(this.CropX_Scroll); // // UploadImage // this.UploadImage.Anchor = System.Windows.Forms.AnchorStyles.Bottom; this.UploadImage.Location = new System.Drawing.Point(88, 246); this.UploadImage.Name = "UploadImage"; this.UploadImage.Size = new System.Drawing.Size(104, 23); this.UploadImage.TabIndex = 5; this.UploadImage.TabStop = false; this.UploadImage.Text = "Upload Image"; this.UploadImage.Click += new System.EventHandler(this.UploadImage_Click); // // ListImages // this.ListImages.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Right))); this.ListImages.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.ListImages.Location = new System.Drawing.Point(289, 24); this.ListImages.Name = "ListImages"; this.ListImages.ScrollAlwaysVisible = true; this.ListImages.Size = new System.Drawing.Size(184, 158); this.ListImages.TabIndex = 6; this.ListImages.TabStop = false; this.ListImages.DoubleClick += new System.EventHandler(this.ListImages_DoubleClick); // // ListImagesLabel // this.ListImagesLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.ListImagesLabel.AutoSize = true; this.ListImagesLabel.BackColor = System.Drawing.Color.Transparent; this.ListImagesLabel.Location = new System.Drawing.Point(273, 8); this.ListImagesLabel.Name = "ListImagesLabel"; this.ListImagesLabel.Size = new System.Drawing.Size(78, 13); this.ListImagesLabel.TabIndex = 7; this.ListImagesLabel.Text = "Images to Use:"; // // GenerateHTML // this.GenerateHTML.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.GenerateHTML.Location = new System.Drawing.Point(327, 210); this.GenerateHTML.Name = "GenerateHTML"; this.GenerateHTML.Size = new System.Drawing.Size(104, 23); this.GenerateHTML.TabIndex = 8; this.GenerateHTML.TabStop = false; this.GenerateHTML.Text = "Copy Image Code"; this.GenerateHTML.Click += new System.EventHandler(this.GenerateHTML_Click); // // ClearImages // this.ClearImages.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.ClearImages.Location = new System.Drawing.Point(327, 246); this.ClearImages.Name = "ClearImages"; this.ClearImages.Size = new System.Drawing.Size(104, 23); this.ClearImages.TabIndex = 9; this.ClearImages.TabStop = false; this.ClearImages.Text = "Clear Image List"; this.ClearImages.Click += new System.EventHandler(this.ClearImages_Click); // // ImageToolTip // this.ImageToolTip.AutomaticDelay = 250; this.ImageToolTip.AutoPopDelay = 0; this.ImageToolTip.InitialDelay = 250; this.ImageToolTip.ReshowDelay = 10; // // btnListMoveUp // this.btnListMoveUp.AccessibleRole = System.Windows.Forms.AccessibleRole.None; this.btnListMoveUp.Anchor = System.Windows.Forms.AnchorStyles.Right; this.btnListMoveUp.FlatAppearance.BorderSize = 0; this.btnListMoveUp.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.btnListMoveUp.Image = global::eBay_Images.Properties.Resources.MoveUp; this.btnListMoveUp.Location = new System.Drawing.Point(475, 59); this.btnListMoveUp.Name = "btnListMoveUp"; this.btnListMoveUp.Size = new System.Drawing.Size(32, 26); this.btnListMoveUp.TabIndex = 10; this.btnListMoveUp.TabStop = false; this.ImageToolTip.SetToolTip(this.btnListMoveUp, "Move Up"); this.btnListMoveUp.UseVisualStyleBackColor = true; this.btnListMoveUp.Click += new System.EventHandler(this.btnListMoveUp_Click); // // btnListDelete // this.btnListDelete.AccessibleRole = System.Windows.Forms.AccessibleRole.None; this.btnListDelete.Anchor = System.Windows.Forms.AnchorStyles.Right; this.btnListDelete.FlatAppearance.BorderSize = 0; this.btnListDelete.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.btnListDelete.Image = global::eBay_Images.Properties.Resources.Delete; this.btnListDelete.Location = new System.Drawing.Point(475, 93); this.btnListDelete.Name = "btnListDelete"; this.btnListDelete.Size = new System.Drawing.Size(32, 26); this.btnListDelete.TabIndex = 11; this.btnListDelete.TabStop = false; this.ImageToolTip.SetToolTip(this.btnListDelete, "Remove"); this.btnListDelete.UseVisualStyleBackColor = true; this.btnListDelete.Click += new System.EventHandler(this.btnListDelete_Click); // // btnListMoveDown // this.btnListMoveDown.AccessibleRole = System.Windows.Forms.AccessibleRole.None; this.btnListMoveDown.Anchor = System.Windows.Forms.AnchorStyles.Right; this.btnListMoveDown.FlatAppearance.BorderSize = 0; this.btnListMoveDown.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.btnListMoveDown.Image = global::eBay_Images.Properties.Resources.MoveDown; this.btnListMoveDown.Location = new System.Drawing.Point(475, 127); this.btnListMoveDown.Name = "btnListMoveDown"; this.btnListMoveDown.Size = new System.Drawing.Size(32, 26); this.btnListMoveDown.TabIndex = 12; this.btnListMoveDown.TabStop = false; this.ImageToolTip.SetToolTip(this.btnListMoveDown, "Move Down"); this.btnListMoveDown.UseVisualStyleBackColor = true; this.btnListMoveDown.Click += new System.EventHandler(this.btnListMoveDown_Click); // // btnImageRotateLeft // this.btnImageRotateLeft.AccessibleRole = System.Windows.Forms.AccessibleRole.None; this.btnImageRotateLeft.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btnImageRotateLeft.FlatAppearance.BorderSize = 0; this.btnImageRotateLeft.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.btnImageRotateLeft.Image = global::eBay_Images.Properties.Resources.EditRedo; this.btnImageRotateLeft.Location = new System.Drawing.Point(0, 185); this.btnImageRotateLeft.Name = "btnImageRotateLeft"; this.btnImageRotateLeft.Size = new System.Drawing.Size(32, 26); this.btnImageRotateLeft.TabIndex = 14; this.btnImageRotateLeft.TabStop = false; this.ImageToolTip.SetToolTip(this.btnImageRotateLeft, "Rotate Left"); this.btnImageRotateLeft.UseVisualStyleBackColor = true; this.btnImageRotateLeft.Click += new System.EventHandler(this.btnImageRotateLeft_Click); // // btnImageRotateRight // this.btnImageRotateRight.AccessibleRole = System.Windows.Forms.AccessibleRole.None; this.btnImageRotateRight.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.btnImageRotateRight.FlatAppearance.BorderSize = 0; this.btnImageRotateRight.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.btnImageRotateRight.Image = global::eBay_Images.Properties.Resources.EditRedo; this.btnImageRotateRight.Location = new System.Drawing.Point(244, 185); this.btnImageRotateRight.Name = "btnImageRotateRight"; this.btnImageRotateRight.Size = new System.Drawing.Size(32, 26); this.btnImageRotateRight.TabIndex = 13; this.btnImageRotateRight.TabStop = false; this.ImageToolTip.SetToolTip(this.btnImageRotateRight, "Rotate Right"); this.btnImageRotateRight.UseVisualStyleBackColor = true; this.btnImageRotateRight.Click += new System.EventHandler(this.btnImageRotateRight_Click); // // ImageResize // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(507, 273); this.Controls.Add(this.btnImageRotateLeft); this.Controls.Add(this.btnImageRotateRight); this.Controls.Add(this.btnListMoveDown); this.Controls.Add(this.btnListDelete); this.Controls.Add(this.btnListMoveUp); this.Controls.Add(this.ListImages); this.Controls.Add(this.ClearImages); this.Controls.Add(this.GenerateHTML); this.Controls.Add(this.UploadImage); this.Controls.Add(this.CropWidth); this.Controls.Add(this.CropX); this.Controls.Add(this.CropHeight); this.Controls.Add(this.CropY); this.Controls.Add(this.PictureBox1); this.Controls.Add(this.LoadImage); this.Controls.Add(this.ListImagesLabel); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; this.MinimumSize = new System.Drawing.Size(515, 300); this.Name = "ImageResize"; this.Text = "eBay Images"; this.Load += new System.EventHandler(this.ImageResize_Load); this.Resize += new System.EventHandler(this.ImageResize_Resize); this.ResizeEnd += new System.EventHandler(this.ImageResize_ResizeEnd); ((System.ComponentModel.ISupportInitialize)(this.PictureBox1)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion /// /// The main entry point for the application. /// [STAThread] static void Main() { // fix non-compliant webservers ServicePointManager.Expect100Continue = false; Application.ThreadException += new ThreadExceptionEventHandler(new ExceptionHelper().MainThreadException); Application.Run(new ImageResize()); } #region Exception Helper Class /// /// Helper for interacting with Exceptions. /// public class ExceptionHelper { #region Write Exception Log /// /// Take an Exception and optionally another String and write them to a log file. /// /// Exception to include in the log file. /// Additional string of text to include after the exception. /// True if successfully written, otherwise false. public static bool WriteExceptionLog(Exception e, String addendum = "") { bool logged = false; try { DateTime ErrorTime = DateTime.Now; FileInfo exe = new FileInfo(Application.ExecutablePath); DirectoryInfo AppPath = exe.Directory; FileStream LogFile = new FileStream(String.Format(@"{0}\error_{1:yyyyMMdd-HHmmss}.txt", AppPath.FullName, ErrorTime), FileMode.Create, FileAccess.Write, FileShare.Read); StreamWriter LogWriter = new StreamWriter(LogFile); LogWriter.WriteLine(ErrorTime.ToString("MM/dd/yyyy HH:mm:ss")); LogWriter.WriteLine(Application.ProductVersion); LogWriter.WriteLine(Environment.NewLine); LogWriter.WriteLine("Exception:"); LogWriter.WriteLine(e.ToString()); if (String.IsNullOrEmpty(addendum) == false) { LogWriter.WriteLine(Environment.NewLine); LogWriter.WriteLine(addendum); } LogWriter.Flush(); LogWriter.Close(); logged = true; } catch { logged = false; } return logged; } #endregion #region Main Thread Exception /// /// Generic exception handler to catch otherwise uncaught exceptions. /// public void MainThreadException(object sender, ThreadExceptionEventArgs e) { Boolean Logged = WriteExceptionLog(e.Exception); MessageBox.Show(String.Format("{0}Thread Error:{1}{2}", (Logged ? "Logged " : String.Empty), Environment.NewLine, e.Exception.ToString()), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } #endregion } #endregion #region Global Variables // store the current image we're working on Image OriginalImage, PreviewImage; // and a global for the scaling factor double ScaleFactor = 1; // and the 'crop' rectangle - global for use in CreateCropBox Rectangle CropRect = new Rectangle(); #endregion #region ImageResize_Load /// /// Form_Load Event, initialize stuff programatically /// private void ImageResize_Load(object sender, System.EventArgs e) { if (OriginalImage != null) OriginalImage.Dispose(); if (PreviewImage != null) PreviewImage.Dispose(); PictureBox1.Image = null; // TODO: see if any of this can be moved to FixGui() to simplify initialization this.CropX.Minimum = 0; this.CropX.Maximum = PictureBox1.Width; this.CropY.Minimum = 0; this.CropY.Maximum = PictureBox1.Height; this.CropWidth.Minimum = 0; this.CropWidth.Maximum = PictureBox1.Width; this.CropHeight.Minimum = 0; this.CropHeight.Maximum = PictureBox1.Height; this.CropX.Enabled = false; this.CropY.Enabled = false; this.CropWidth.Enabled = false; this.CropHeight.Enabled = false; this.btnImageRotateLeft.Enabled = false; this.btnImageRotateRight.Enabled = false; this.UploadImage.Enabled = false; this.GenerateHTML.Enabled = false; this.ClearImages.Enabled = false; CropRect.X = CropX.Value; CropRect.Y = CropY.Value; CropRect.Width = CropWidth.Value; CropRect.Height = CropHeight.Value; } #endregion #region ScrollBar Events // idiosyncracy with scrollbars: // the actual maximum scrollable value is ScrollBar.Maximum - ScrollBar.LargeChange + 1 // therefore, we set ScrollBar.LargeChange = 1 private void CropX_Scroll(object sender, System.Windows.Forms.ScrollEventArgs e) { CropRect.X = e.NewValue; CreateCropBox(); this.ImageToolTip.SetToolTip(this.PictureBox1, "Dimensions after resize and crop: " + CalculateDimensionsAfterCropAndResize()); } private void CropY_Scroll(object sender, System.Windows.Forms.ScrollEventArgs e) { CropRect.Y = e.NewValue; CreateCropBox(); this.ImageToolTip.SetToolTip(this.PictureBox1, "Dimensions after resize and crop: " + CalculateDimensionsAfterCropAndResize()); } private void CropWidth_Scroll(object sender, System.Windows.Forms.ScrollEventArgs e) { CropRect.Width = e.NewValue; CreateCropBox(); this.ImageToolTip.SetToolTip(this.PictureBox1, "Dimensions after resize and crop: " + CalculateDimensionsAfterCropAndResize()); } private void CropHeight_Scroll(object sender, System.Windows.Forms.ScrollEventArgs e) { CropRect.Height = e.NewValue; CreateCropBox(); this.ImageToolTip.SetToolTip(this.PictureBox1, "Dimensions after resize and crop: " + CalculateDimensionsAfterCropAndResize()); } #endregion #region LoadImage_Click // TODO: parts of this were simply copied into ImageResize_Resize // break out sommon parts into a helper function private void LoadImage_Click(object sender, System.EventArgs e) { if (openFileDialog1.ShowDialog() == DialogResult.OK) { if (OriginalImage != null) OriginalImage.Dispose(); if (PreviewImage != null) PreviewImage.Dispose(); // load the desired image into temporary storage OriginalImage = Image.FromFile(openFileDialog1.FileName); UpdatePreviewImage(); FixGui(); } } #endregion #region btnImageRotateLeft_Click private void btnImageRotateLeft_Click(object sender, EventArgs e) { OriginalImage.RotateFlip(RotateFlipType.Rotate270FlipNone); UpdatePreviewImage(); } #endregion #region btnImageRotateRight_Click private void btnImageRotateRight_Click(object sender, EventArgs e) { OriginalImage.RotateFlip(RotateFlipType.Rotate90FlipNone); UpdatePreviewImage(); } #endregion #region UploadImage_Click private void UploadImage_Click(object sender, System.EventArgs e) { WaitingGui(); Rectangle cropped = new Rectangle(CropRect.X, CropRect.Y, CropRect.Width, CropRect.Height); // normalize the cropbox to the original image pixels NormalizeCropCoords(ref cropped); // generate the cropped image Image CroppedImage = ResizeImage(OriginalImage, new Rectangle(0, 0, cropped.Width, cropped.Height), cropped); if (cropped.Width > 550) { double reScaleFactor = 550 / (double)cropped.Width; // we can reuse this ... cropped.X = 0; cropped.Y = 0; cropped.Width = (int)(cropped.Width * reScaleFactor); cropped.Height = (int)(cropped.Height * reScaleFactor); CroppedImage = ResizeImage(CroppedImage, cropped, new Rectangle(0, 0, CroppedImage.Width, CroppedImage.Height)); } // all we care about for final size constraints is the width, and that the image // itself is bigger than 200x200 if (CroppedImage.Width > 200 && CroppedImage.Height > 200) { // big try loop in case the http transaction fails string response = String.Empty; try { // make the image a memory stream to convert to a byte array MemoryStream msCroppedImage = new MemoryStream(); // put the image into the stream CroppedImage.Save(msCroppedImage, System.Drawing.Imaging.ImageFormat.Jpeg); // byte array for the stream byte[] CroppedImageJPEG = new byte[msCroppedImage.Length]; // make sure the stream starts at the beginning msCroppedImage.Position = 0; // finally copy the stream into the byte array msCroppedImage.Read(CroppedImageJPEG, 0, (int)msCroppedImage.Length); var filename = Path.GetFileName(openFileDialog1.FileName); var img = ImgurV3.Upload(CroppedImageJPEG, filename); response = img.Raw; // and add the item to the list ListImages.Items.Add(new ImageInfo( GetFileMD5(openFileDialog1.FileName), filename, img.Image, img.Thumbnail, CroppedImage.Width, CroppedImage.Height )); // since we worked, lets clean up stuff this.PictureBox1.Image = null; PreviewImage.Dispose(); PreviewImage = null; OriginalImage.Dispose(); OriginalImage = null; } catch (Exception ex) { Boolean Logged = ExceptionHelper.WriteExceptionLog(ex, response); string ErrorMessage = String.Format( "{0}Upload Error!" + Environment.NewLine + Environment.NewLine + "{1}", (Logged ? "Logged " : ""), ex.ToString() ); MessageBox.Show(ErrorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } else { MessageBox.Show("The cropped area is too small to generate a thumbnail!\n\nIt is currently " + CalculateDimensionsAfterCropAndResize() + ", but needs to be at greater than 200x200!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } FixGui(); } #endregion #region GenerateHTML_Click private void GenerateHTML_Click(object sender, System.EventArgs e) { // NOTE: no more borders, imageshack started adding them to the thumbnails StringBuilder result = new StringBuilder(); int i = ListImages.Items.Count, j = 0; ImageInfo info = ListImages.Items[j] as ImageInfo; if (i > 0) { result.Append("\r\n"); // duplication of code vs. skipping the fist chunk of the for loop on all // but the first iteration // kind of a toss-up // odd number if (i % 2 == 1) { result.Append("\t\r\n"); // if there is only one image total, we don't need colspan if (i == 1) result.Append("\t\t\r\n"); result.Append("\t\r\n"); j++; } for (; j < i; j++) { info = ListImages.Items[j] as ImageInfo; // 'left' column // if 'current item - 1 (if odd total)' is even, we're in the left col if ((j - (i % 2)) % 2 == 0) { result.Append("\t\r\n"); } // the cell result.Append("\t\t\r\n"); // 'right' column // if 'current item - 1 (if odd total)' is even, we're in the right col if ((j - (i % 2)) % 2 == 1) { result.Append("\t\r\n"); } } result.Append("
\r\n"); else result.Append("\t\t\r\n"); result.Append("\t\t\t" + info.GetThumbnailHtml() + "\r\n"); result.Append("\t\t
\r\n"); result.Append("\t\t\t" + info.GetThumbnailHtml() + "\r\n"); result.Append("\t\t
\r\n"); Clipboard.SetDataObject(result.ToString(), true); MessageBox.Show("The thumbnail HTML has been copied to the clipboard.", "HTML Copied", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show("You must add some images!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error); } } #endregion #region ClearImages_Click private void ClearImages_Click(object sender, System.EventArgs e) { if (MessageBox.Show("Are you sure that you want to clear the image list?", this.Text, MessageBoxButtons.YesNo) != DialogResult.No) { this.ListImages.Items.Clear(); this.ListImagesLabel.Text = "Images to Use:"; FixGui(); } } #endregion #region ListImages_DoubleClick private void ListImages_DoubleClick(object sender, EventArgs e) { // this function allows a double-click of the list to return the link to just that file if (ListImages.SelectedIndex > -1) { ImageInfo info = ListImages.SelectedItem as ImageInfo; Clipboard.SetDataObject(info.ImageHref, true); MessageBox.Show("Copied URL for " + info.Filename + " to the clipboard", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information); } } #endregion #region btnListMoveUp_Click private void btnListMoveUp_Click(object sender, EventArgs e) { if (ListImages.SelectedIndex > 0) { SwapListItems(ListImages, ListImages.SelectedIndex, ListImages.SelectedIndex - 1); ListImages.SelectedIndex--; } } #endregion #region btnListMoveDown_Click private void btnListMoveDown_Click(object sender, EventArgs e) { if (ListImages.SelectedIndex > -1 && ListImages.SelectedIndex < (ListImages.Items.Count - 1)) { SwapListItems(ListImages, ListImages.SelectedIndex, ListImages.SelectedIndex + 1); ListImages.SelectedIndex++; } } #endregion #region btnListDelete_Click private void btnListDelete_Click(object sender, EventArgs e) { if (ListImages.SelectedIndex > -1) { ListImages.Items.RemoveAt(ListImages.SelectedIndex); FixGui(); } } #endregion #region Helper Functions #region ResizeImage /// /// Resize an Image given a Rectangle to fit it into. /// /// The Image to Resize /// The Rectangle area to fit it into. /// A MemoryStream with the resized image. private Image ResizeImage(Image ImageToResize, Rectangle NewSize, Rectangle SourceArea) { // the image to return Image retval; // the stream that will contain the image returned to the caller MemoryStream ms = new MemoryStream(); // build the container for the resized image Bitmap bmp = new Bitmap(NewSize.Width, NewSize.Height); Graphics g = Graphics.FromImage(bmp); // perform a high quality bicubic resize g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.DrawImage(ImageToResize, NewSize, SourceArea, GraphicsUnit.Pixel); // copy the image to the stream bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); // and build the returned image from the stream retval = Image.FromStream(ms); // cleanup bmp.Dispose(); g.Dispose(); return retval; } #endregion #region UpdatePreviewImage private void UpdatePreviewImage() { if (this.PictureBox1.Image != null) PictureBox1.Image.Dispose(); // find the scaling factor for the preview image ScaleFactor = FindScalingFactor(OriginalImage, PictureBox1.Width, PictureBox1.Height); // the receiving area for the preview version Rectangle dest = new Rectangle(); dest.X = 0; dest.Y = 0; dest.Width = (int)(OriginalImage.Width * ScaleFactor); dest.Height = (int)(OriginalImage.Height * ScaleFactor); // store the resized image in the PreviewImage global // for use by CreateCropBox() PreviewImage = ResizeImage(OriginalImage, dest, new Rectangle(0, 0, OriginalImage.Width, OriginalImage.Height)); // load the preview image into the picture box this.PictureBox1.Image = PreviewImage; // manually do what the scroll events would do -- select the whole image initially CropRect.X = this.CropX.Value = this.CropX.Minimum; CropRect.Y = this.CropY.Value = this.CropY.Minimum; CropRect.Width = this.CropWidth.Value = this.CropWidth.Maximum; CropRect.Height = this.CropHeight.Value = this.CropHeight.Maximum; CreateCropBox(); this.ImageToolTip.SetToolTip(this.PictureBox1, "Dimensions after resize and crop: " + CalculateDimensionsAfterCropAndResize()); } #endregion #region CreateCropBox /// /// Draws the Cropping Box on the PreviewImage (non-destructively) and places that new Image in the PictureBox. /// private void CreateCropBox() { // temp image to have cropbox overlain Image WithCropBox = (Image)PreviewImage.Clone(); // bind g to that temp image Graphics g = Graphics.FromImage(WithCropBox); // add the cropping rectangle g.DrawRectangle(new Pen(Brushes.Azure, 2), CropRect); // cleanup g.Dispose(); // and output it to the picture box PictureBox1.Image = WithCropBox; } #endregion #region FindScalingFactor /// /// Calculate the scaling factor to reduce an image by to fit it into a MaxWidth x MaxHeight area. /// /// The image to scale to fit in a MaxWidth x MaxHeight area. /// Maximum width of the area to contain OriginalImage. /// Maximum height of the area to contain OriginalImage. /// The scaling factor of OriginalImage to make it fit within a MaxWidth x MaxHeight area, or 1 if it will fit. double FindScalingFactor(Image OriginalImage, int MaxWidth, int MaxHeight) { double scaleFactorWidth = 1, scaleFactorHeight = 1; if (OriginalImage.Width > MaxWidth) { scaleFactorWidth = (double)MaxWidth / (double)OriginalImage.Width; } if (OriginalImage.Height > MaxHeight) { scaleFactorHeight = (double)MaxHeight / (double)OriginalImage.Height; } // return the scale factor that will scale the image the most return Math.Min(scaleFactorWidth, scaleFactorHeight); } #endregion #region NormalizeCropCoords private void NormalizeCropCoords(ref Rectangle coords) { // normalize the cropped box to the actual image double unScaleFactor = 1 / ScaleFactor; coords.X = (int)(coords.X * unScaleFactor); coords.Y = (int)(coords.Y * unScaleFactor); coords.Width = (int)(coords.Width * unScaleFactor); coords.Height = (int)(coords.Height * unScaleFactor); // crop only parts of the image -- not beyond // -- do after the normalize to make sure if the whole image is desired we comply if (coords.X + coords.Width > OriginalImage.Width) { coords.Width = OriginalImage.Width - coords.X; } if (coords.Y + coords.Height > OriginalImage.Height) { coords.Height = OriginalImage.Height - coords.Y; } } #endregion #region CalculateDimensionsAfterCropAndResize private string CalculateDimensionsAfterCropAndResize() { Rectangle cropped = new Rectangle(CropRect.X, CropRect.Y, CropRect.Width, CropRect.Height); NormalizeCropCoords(ref cropped); if (cropped.Width > 550) { double reScaleFactor = 550 / (double)cropped.Width; // we can reuse this ... cropped.X = 0; cropped.Y = 0; cropped.Width = (int)(cropped.Width * reScaleFactor); cropped.Height = (int)(cropped.Height * reScaleFactor); } return String.Format("{0}x{1}", cropped.Width, cropped.Height); } #endregion #region SwapArrayListItems /// /// Swaps two items in an ArrayList /// /// List to perform the swap on /// First element to swap /// Second element to swap private void SwapListItems(ListBox List, int x, int y) { if (x > List.Items.Count) throw new ArgumentOutOfRangeException("x"); if (y > List.Items.Count) throw new ArgumentOutOfRangeException("y"); object tmp = List.Items[x]; List.Items[x] = List.Items[y]; List.Items[y] = tmp; } #endregion #region GetFileMD5 private string GetFileMD5(string Path) { StringBuilder sb = new StringBuilder(); FileStream fs = new FileStream(Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); byte[] checksum = md5.ComputeHash(fs); fs.Close(); foreach (byte b in checksum) sb.AppendFormat("{0:X2}", b); return sb.ToString(); } #endregion #endregion #region GUI Management #region WatingGui private void WaitingGui() { this.Cursor = Cursors.WaitCursor; this.LoadImage.Enabled = false; this.UploadImage.Enabled = false; this.GenerateHTML.Enabled = false; this.ClearImages.Enabled = false; this.CropX.Enabled = false; this.CropY.Enabled = false; this.CropWidth.Enabled = false; this.CropHeight.Enabled = false; this.btnImageRotateLeft.Enabled = false; this.btnImageRotateRight.Enabled = false; } #endregion #region FixGui private void FixGui() { this.LoadImage.Enabled = true; if (this.PictureBox1.Image != null) { this.UploadImage.Enabled = true; this.CropX.Enabled = true; this.CropY.Enabled = true; this.CropWidth.Enabled = true; this.CropHeight.Enabled = true; this.btnImageRotateLeft.Enabled = true; this.btnImageRotateRight.Enabled = true; } else { this.UploadImage.Enabled = false; this.CropX.Value = this.CropX.Minimum; this.CropY.Value = this.CropY.Minimum; this.CropWidth.Value = this.CropWidth.Minimum; this.CropHeight.Value = this.CropHeight.Minimum; this.CropX.Enabled = false; this.CropY.Enabled = false; this.CropWidth.Enabled = false; this.CropHeight.Enabled = false; this.btnImageRotateLeft.Enabled = false; this.btnImageRotateRight.Enabled = false; this.ImageToolTip.RemoveAll(); } if (this.ListImages.Items.Count > 0) { this.GenerateHTML.Enabled = true; this.ClearImages.Enabled = true; this.ListImagesLabel.Text = String.Format("Images to Use [ {0} ] :", this.ListImages.Items.Count); } else { this.GenerateHTML.Enabled = false; this.ClearImages.Enabled = false; this.ListImagesLabel.Text = "Images to Use:"; } this.Cursor = Cursors.Default; this.Refresh(); } #endregion #region Resize Handlers private void ImageResize_Resize(object sender, EventArgs e) { if (OriginalImage == null) return; if (this.WindowState == FormWindowState.Minimized) return; // find the scaling factor for the preview image ScaleFactor = FindScalingFactor(OriginalImage, PictureBox1.Width, PictureBox1.Height); // the receiving area for the preview version Rectangle dest = new Rectangle(); dest.X = 0; dest.Y = 0; dest.Width = (int)(OriginalImage.Width * ScaleFactor); dest.Height = (int)(OriginalImage.Height * ScaleFactor); // store the resized image in the PreviewImage global // for use by CreateCropBox() PreviewImage = ResizeImage(OriginalImage, dest, new Rectangle(0, 0, OriginalImage.Width, OriginalImage.Height)); // load the preview image into the picture box this.PictureBox1.Image = PreviewImage; // fix the scroll bars this.CropX.Minimum = 0; this.CropX.Maximum = PictureBox1.Width; this.CropY.Minimum = 0; this.CropY.Maximum = PictureBox1.Height; this.CropWidth.Minimum = 0; this.CropWidth.Maximum = PictureBox1.Width; this.CropHeight.Minimum = 0; this.CropHeight.Maximum = PictureBox1.Height; CropRect.X = CropX.Value; CropRect.Y = CropY.Value; CropRect.Width = CropWidth.Value; CropRect.Height = CropHeight.Value; if (this.WindowState != FormWindowState.Minimized) { CreateCropBox(); } } private void ImageResize_ResizeEnd(object sender, EventArgs e) { if (PreviewImage == null) return; CreateCropBox(); FixGui(); } #endregion #region System Menu Handler protected override void WndProc(ref Message m) { base.WndProc(ref m); if(m.Msg == User32.WM_SYSCOMMAND) { if(m.WParam.ToInt32() == 0x200) { About aboutForm = new About(); aboutForm.ShowDialog(); } } } #endregion #endregion } #region ImageInfo Class public sealed class ImageInfo { #region Member Variables private string _Hash = String.Empty; private string _Filename = String.Empty; private string _ImageHref = String.Empty; private string _ThumbHref = String.Empty; private int _Width = 0; private int _Height = 0; #endregion #region Constructor public ImageInfo(string Hash) { this.Hash = Hash; } public ImageInfo(string Hash, string Filename) { this.Hash = Hash; this.Filename = Filename; } public ImageInfo(string Hash, string Filename, string ImageHref, string ThumbHref, int Width, int Height) { this.Hash = Hash; this.Filename = Filename; this.ImageHref = ImageHref; this.ThumbHref = ThumbHref; this._Width = Width; this._Height = Height; } #endregion #region Properties #region Hash public string Hash { get { return _Hash; } set { if (value == null || value.Length == 0) throw new ArgumentNullException("Hash"); _Hash = value; } } #endregion #region Filename public string Filename { get { return _Filename; } set { if (value == null || value.Length == 0) throw new ArgumentNullException("Filename"); _Filename = value; } } #endregion #region ImageHref public string ImageHref { get { return _ImageHref; } set { if (value == null || value.Length == 0) throw new ArgumentNullException("ImageHref"); _ImageHref = value; } } #endregion #region ThumbHref public string ThumbHref { get { return _ThumbHref; } set { if (value == null || value.Length == 0) throw new ArgumentNullException("ThumbHref"); _ThumbHref = value; } } #endregion #region Width public int Width { get { return _Width; } set { _Width = value; } } #endregion #region Height public int Height { get { return _Height; } set { _Height = value; } } #endregion #endregion #region GetThumbnailHtml public string GetThumbnailHtml() { return String.Format("\"{2}\"", _ImageHref, _ThumbHref, _Filename ); } #endregion #region ToString public override string ToString() { return String.Format("{0} ({1}x{2})", _Filename, _Width, _Height); } #endregion } #endregion }