using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.IO; using System.Threading; using ICSharpCode.SharpZipLib.Zip; using System.Drawing.Imaging; namespace WmPhotoZipper{ /// /// This tiny, but powerfull tool will prevent a enormous load of help /// calls. It replaces the FTP upload system by zipping photo's and rezising them /// before they are sent to the WMIT servers. This reduces the load of our machines /// as well. Oh we are sooo happy. /// 14 july 2006 /// /// Update @ 17th november 2007. The zipper worked very well, but now more is demanded, /// more and more megapixel camera's are being used by the customers and the original ZIP /// lib did not work under Vista. Therefore version 2, optimized for .NET 2.0 was created using /// SharpZipLib. It uses the new BackgroundWorker process for zipping and resizing. /// 17th nov 2007 - Willem /// /// Update @ 29 august 2008. The zipper still performs very well. Updated the binary to work nice /// with the new Core Manager series. Since both bandwidth as server capacity has increased, I /// updated the resolution to 1000x1000 pixels (was 800x800). The new "javascript" way to show images /// is allowing us to use higher res photo's withouth breaking the interface. /// public class MainForm : System.Windows.Forms.Form{ private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog; private System.Windows.Forms.Button chooseFolderButton; private System.Windows.Forms.Label instructionLbl; private System.Windows.Forms.GroupBox instructionsBox; private System.Windows.Forms.GroupBox selectFolderBox; private System.Windows.Forms.GroupBox processingBox; private System.Windows.Forms.ProgressBar progressBar; private System.Windows.Forms.Label selectFolderInstructionsLbl; private System.Windows.Forms.Label selectResultsLbl; private System.Windows.Forms.Label amountPhotosInstructionLbl; private System.Windows.Forms.Label photoCountLbl; private System.Windows.Forms.Button zipPhotosButton; private System.ComponentModel.Container components = null; private BackgroundWorker photoZipper; protected string myPicturesPath; protected string desktopPath; protected string photoPath; protected string targetPath; private Label copyrightLbl; protected string tmpPath; public MainForm(){ InitializeComponent(); desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); targetPath = desktopPath + "\\ingepakte_fotos.zip"; myPicturesPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures); folderBrowserDialog.SelectedPath = myPicturesPath; copyrightLbl.Text = "V"+System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); } 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() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); this.folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog(); this.chooseFolderButton = new System.Windows.Forms.Button(); this.instructionLbl = new System.Windows.Forms.Label(); this.instructionsBox = new System.Windows.Forms.GroupBox(); this.selectFolderBox = new System.Windows.Forms.GroupBox(); this.photoCountLbl = new System.Windows.Forms.Label(); this.amountPhotosInstructionLbl = new System.Windows.Forms.Label(); this.selectResultsLbl = new System.Windows.Forms.Label(); this.selectFolderInstructionsLbl = new System.Windows.Forms.Label(); this.processingBox = new System.Windows.Forms.GroupBox(); this.zipPhotosButton = new System.Windows.Forms.Button(); this.progressBar = new System.Windows.Forms.ProgressBar(); this.photoZipper = new System.ComponentModel.BackgroundWorker(); this.copyrightLbl = new System.Windows.Forms.Label(); this.instructionsBox.SuspendLayout(); this.selectFolderBox.SuspendLayout(); this.processingBox.SuspendLayout(); this.SuspendLayout(); // // folderBrowserDialog // this.folderBrowserDialog.Description = "Selecteer de map met foto\'s die u wilt inpakken."; this.folderBrowserDialog.ShowNewFolderButton = false; // // chooseFolderButton // this.chooseFolderButton.Location = new System.Drawing.Point(104, 32); this.chooseFolderButton.Name = "chooseFolderButton"; this.chooseFolderButton.Size = new System.Drawing.Size(120, 23); this.chooseFolderButton.TabIndex = 0; this.chooseFolderButton.Text = "Kies map met foto\'s"; this.chooseFolderButton.Click += new System.EventHandler(this.chooseFolderButton_Click); // // instructionLbl // this.instructionLbl.Location = new System.Drawing.Point(8, 16); this.instructionLbl.Name = "instructionLbl"; this.instructionLbl.Size = new System.Drawing.Size(320, 40); this.instructionLbl.TabIndex = 1; this.instructionLbl.Text = "De foto inpakker helpt u bij het klaarmaken van een ZIP bestand voor de Manager. " + "U kunt de ingepakte map met foto\'s direct gebruiken in uw Manager."; // // instructionsBox // this.instructionsBox.Controls.Add(this.instructionLbl); this.instructionsBox.Location = new System.Drawing.Point(8, 8); this.instructionsBox.Name = "instructionsBox"; this.instructionsBox.Size = new System.Drawing.Size(336, 64); this.instructionsBox.TabIndex = 2; this.instructionsBox.TabStop = false; this.instructionsBox.Text = "Introductie"; // // selectFolderBox // this.selectFolderBox.Controls.Add(this.photoCountLbl); this.selectFolderBox.Controls.Add(this.amountPhotosInstructionLbl); this.selectFolderBox.Controls.Add(this.selectResultsLbl); this.selectFolderBox.Controls.Add(this.selectFolderInstructionsLbl); this.selectFolderBox.Controls.Add(this.chooseFolderButton); this.selectFolderBox.Location = new System.Drawing.Point(8, 80); this.selectFolderBox.Name = "selectFolderBox"; this.selectFolderBox.Size = new System.Drawing.Size(336, 112); this.selectFolderBox.TabIndex = 3; this.selectFolderBox.TabStop = false; this.selectFolderBox.Text = "Map Selecteren"; // // photoCountLbl // this.photoCountLbl.Enabled = false; this.photoCountLbl.Location = new System.Drawing.Point(224, 80); this.photoCountLbl.Name = "photoCountLbl"; this.photoCountLbl.Size = new System.Drawing.Size(100, 16); this.photoCountLbl.TabIndex = 4; this.photoCountLbl.Text = "0"; this.photoCountLbl.TextAlign = System.Drawing.ContentAlignment.TopRight; // // amountPhotosInstructionLbl // this.amountPhotosInstructionLbl.Enabled = false; this.amountPhotosInstructionLbl.Location = new System.Drawing.Point(8, 80); this.amountPhotosInstructionLbl.Name = "amountPhotosInstructionLbl"; this.amountPhotosInstructionLbl.Size = new System.Drawing.Size(160, 16); this.amountPhotosInstructionLbl.TabIndex = 3; this.amountPhotosInstructionLbl.Text = "Aantal foto\'s gevonden in map:"; // // selectResultsLbl // this.selectResultsLbl.Enabled = false; this.selectResultsLbl.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.selectResultsLbl.Location = new System.Drawing.Point(8, 64); this.selectResultsLbl.Name = "selectResultsLbl"; this.selectResultsLbl.Size = new System.Drawing.Size(312, 16); this.selectResultsLbl.TabIndex = 2; this.selectResultsLbl.Text = "Geen map geselecteerd."; // // selectFolderInstructionsLbl // this.selectFolderInstructionsLbl.Location = new System.Drawing.Point(8, 16); this.selectFolderInstructionsLbl.Name = "selectFolderInstructionsLbl"; this.selectFolderInstructionsLbl.Size = new System.Drawing.Size(256, 16); this.selectFolderInstructionsLbl.TabIndex = 1; this.selectFolderInstructionsLbl.Text = "Selecteer de map met foto\'s die u wilt inpakken:"; // // processingBox // this.processingBox.Controls.Add(this.zipPhotosButton); this.processingBox.Controls.Add(this.progressBar); this.processingBox.Enabled = false; this.processingBox.Location = new System.Drawing.Point(8, 208); this.processingBox.Name = "processingBox"; this.processingBox.Size = new System.Drawing.Size(336, 80); this.processingBox.TabIndex = 4; this.processingBox.TabStop = false; this.processingBox.Text = "Map Inpakken"; // // zipPhotosButton // this.zipPhotosButton.Location = new System.Drawing.Point(104, 16); this.zipPhotosButton.Name = "zipPhotosButton"; this.zipPhotosButton.Size = new System.Drawing.Size(120, 23); this.zipPhotosButton.TabIndex = 1; this.zipPhotosButton.Text = "Foto\'s Inpakken"; this.zipPhotosButton.Click += new System.EventHandler(this.zipPhotosButton_Click); // // progressBar // this.progressBar.Location = new System.Drawing.Point(8, 48); this.progressBar.Name = "progressBar"; this.progressBar.Size = new System.Drawing.Size(320, 23); this.progressBar.TabIndex = 0; // // photoZipper // this.photoZipper.WorkerReportsProgress = true; this.photoZipper.DoWork += new System.ComponentModel.DoWorkEventHandler(this.photoZipper_DoWork); this.photoZipper.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.photoZipper_RunWorkerCompleted); this.photoZipper.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.photoZipper_ProgressChanged); // // copyrightLbl // this.copyrightLbl.Enabled = false; this.copyrightLbl.Font = new System.Drawing.Font("Microsoft Sans Serif", 6F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.copyrightLbl.Location = new System.Drawing.Point(288, 292); this.copyrightLbl.Name = "copyrightLbl"; this.copyrightLbl.Size = new System.Drawing.Size(51, 9); this.copyrightLbl.TabIndex = 5; this.copyrightLbl.Text = "v2.x"; this.copyrightLbl.TextAlign = System.Drawing.ContentAlignment.MiddleRight; // // MainForm // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(352, 303); this.Controls.Add(this.copyrightLbl); this.Controls.Add(this.processingBox); this.Controls.Add(this.selectFolderBox); this.Controls.Add(this.instructionsBox); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "MainForm"; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "WMIT Foto Inpakker "; this.instructionsBox.ResumeLayout(false); this.selectFolderBox.ResumeLayout(false); this.processingBox.ResumeLayout(false); this.ResumeLayout(false); } #endregion [STAThread] static void Main(){ Application.Run(new MainForm()); } private void chooseFolderButton_Click(object sender, System.EventArgs e) { if(DialogResult.OK == folderBrowserDialog.ShowDialog()){ this.amountPhotosInstructionLbl.Enabled = true; this.photoCountLbl.Enabled = true; this.selectResultsLbl.Enabled = true; string selectedFolderText = folderBrowserDialog.SelectedPath; int maxLength = 50; if(selectedFolderText.Length>maxLength){ selectedFolderText = "..."+selectedFolderText.Substring(selectedFolderText.Length-maxLength,maxLength); } this.selectResultsLbl.Text = selectedFolderText; if(checkFolderForPhotoFiles(folderBrowserDialog.SelectedPath)){ this.processingBox.Enabled = true; this.zipPhotosButton.BackColor = Color.LightGreen; }else{ this.processingBox.Enabled = false; this.zipPhotosButton.BackColor = Color.Empty; MessageBox.Show("Sorry, maar in de geselecteerde map kan ik geen foto's vinden.","Geen foto's gevonden",MessageBoxButtons.OK,MessageBoxIcon.Exclamation); } } } protected bool checkFolderForPhotoFiles(string folderPath){ int amountPhotos = 0; amountPhotos += Directory.GetFiles(folderPath,"*.jpg").Length; amountPhotos += Directory.GetFiles(folderPath,"*.png").Length; amountPhotos += Directory.GetFiles(folderPath,"*.jpeg").Length; amountPhotos += Directory.GetFiles(folderPath,"*.bmp").Length; photoCountLbl.Text = amountPhotos.ToString(); return (amountPhotos > 0); } private void zipPhotosButton_Click(object sender, System.EventArgs e) { #region Clear any exsisting file, or return with a message if (File.Exists(targetPath)) { if (DialogResult.Yes == MessageBox.Show("Er staat nog een (oude) ZIP met ingepakte foto's op uw bureaublad." + System.Environment.NewLine + "Wilt u dat ik deze overschrijf?", "Bestaande ZIP gevonden", MessageBoxButtons.YesNo, MessageBoxIcon.Question)) { try { File.Delete(targetPath); } catch { MessageBox.Show("Helaas, het bestand kan niet worden overschreven." + System.Environment.NewLine + "Controleer of het bestand niet wordt gebruikt door een ander programma.", "Bestand Geblokkeerd", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else { return; } } #endregion photoPath = folderBrowserDialog.SelectedPath; zipPhotosButton.Enabled = false; chooseFolderButton.Enabled = false; photoZipper.RunWorkerAsync(); } private void photoZipper_DoWork(object sender, DoWorkEventArgs e) { string tmpPath = Path.GetTempPath() + "\\WMITPhotoZipper-" + DateTime.Now.Ticks; try { Directory.CreateDirectory(tmpPath); } catch (Exception error) { MessageBox.Show("Het lukte niet om de foto\'s in te pakken. Er kon geen tijdelijke map worden aangemaakt: " + Environment.NewLine + tmpPath + Environment.NewLine + "Uw computer gaf de volgende melding: " + Environment.NewLine + error.Message, "Fout bij inpakken foto's", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Directory.SetCurrentDirectory(photoPath); string[] photoFiles = Directory.GetFiles(photoPath); int totalFiles = photoFiles.Length; // Stage one: resizing the photo's for (int i = 0; i <= photoFiles.GetUpperBound(0); i++) { string fileName = Path.GetFileName(photoFiles[i]); string file = photoFiles[i]; if (isPhoto(file)) { // First create small version of image: reziseImage(file, tmpPath); photoZipper.ReportProgress(getPhotoProgressPercentage(totalFiles,i)); Thread.Sleep(10); } } photoZipper.ReportProgress(100); // Stage two: zipping the folder FastZip fastZip = new FastZip(); fastZip.CreateZip(targetPath, tmpPath, false,null); Directory.Delete(tmpPath,true); } protected int getPhotoProgressPercentage(int totalPhotos, int currentIndex) { double processed = currentIndex; double total = totalPhotos; double percentage = processed / total; percentage = Math.Round(percentage * 100); return System.Convert.ToInt32(percentage); } protected bool isPhoto(string path) { path = path.ToLower(); return (path.EndsWith(".jpg") || path.EndsWith(".jpeg") || path.EndsWith(".bmp") || path.EndsWith(".png")); } private void photoZipper_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar.Value = e.ProgressPercentage; } protected void reziseImage(string filePath, string targetPath) { System.IO.FileStream photoStream; Bitmap image; // Create bitmap in memory and delete original photo file photoStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read); try { image = (Bitmap)Bitmap.FromStream(photoStream); image = resizeImage(image, 1000, 1000, false); // Save bitmap as thumbnail image targetPath = targetPath + "//" + Path.GetFileName(filePath); SaveJPGWithCompressionSetting(image, targetPath, 85); } catch { } finally { photoStream.Close(); } } /// /// Returns the image codec info of the specified mimeType (JPG) /// /// /// public ImageCodecInfo GetEncoderInfo(String mimeType) { int j; ImageCodecInfo[] encoders; encoders = ImageCodecInfo.GetImageEncoders(); for (j = 0; j < encoders.Length; ++j) { if (encoders[j].MimeType == mimeType) return encoders[j]; } return null; } /// /// Saves an image with JPG compression. /// /// Image to save /// Destination file name /// Amount of compression public void SaveJPGWithCompressionSetting(System.Drawing.Image image, string szFileName, long lCompression) { EncoderParameters eps = new EncoderParameters(1); eps.Param[0] = new EncoderParameter(Encoder.Quality, lCompression); ImageCodecInfo ici = GetEncoderInfo("image/jpeg"); image.Save(szFileName, ici, eps); } /// /// Resizes an image to a given size. Use cropping to force image to be that size /// /// image object to resize /// Maximum width in pixels /// Maximum height in pixels /// If true, the image will return in the given pixel size /// public Bitmap resizeImage(Bitmap image, int maxWidth, int maxHeight, bool crop) { int height; int width; if (!crop) { if (image.Width > maxWidth || image.Height > maxHeight) { // determine which exeecds the most: width or height double oversizeWidthRatio = ((double)image.Width / maxWidth); double oversizeHeightRatio = ((double)image.Height / maxHeight); if (((double)image.Width / maxWidth) > ((double)image.Height / maxHeight)) { // width is larger and therefore width needs to be decreased double ratio = (double)image.Width / image.Height; width = maxWidth; height = Convert.ToInt32((double)width / ratio); } else { // height is larger and therefore needs to be decreased double ratio = (double)image.Width / image.Height; height = maxHeight; width = Convert.ToInt32((double)height * ratio); } // Newly added high quality resizing: Bitmap bitmap = new Bitmap(width, height, image.PixelFormat); Graphics newG = Graphics.FromImage(bitmap); newG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; newG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear; // Draw 3 times to prevent "black border" newG.DrawImage(image, 0, 0, bitmap.Width, bitmap.Height); newG.DrawImage(image, 0, 0, bitmap.Width, bitmap.Height); newG.DrawImage(image, 0, 0, bitmap.Width, bitmap.Height); newG.Dispose(); return bitmap; } else { height = image.Height; width = image.Width; return new Bitmap(image, width, height); } } else { // CROP MODUS RectangleF rect = new RectangleF(0, 0, maxWidth, maxHeight); int startX = 0; int startY = 0; if (((double)image.Width / maxWidth) < ((double)image.Height / maxHeight)) { // width is smaller and therefore we use this one as ijkpunt. double ratio = (double)image.Width / image.Height; width = maxWidth; height = Convert.ToInt32((double)width / ratio); Bitmap tmp = new Bitmap(width, height, image.PixelFormat); Graphics newG = Graphics.FromImage(tmp); newG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; newG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; // Draw 3 times to prevent "black border" newG.DrawImage(image, 0, 0, tmp.Width, tmp.Height); newG.DrawImage(image, 0, 0, tmp.Width, tmp.Height); newG.DrawImage(image, 0, 0, tmp.Width, tmp.Height); image.Dispose(); newG.Dispose(); // Find out how many pixels need to be cropped startY = (int)System.Math.Floor((double)((tmp.Height - maxHeight) / 2)); Rectangle sourceRectangle = new Rectangle(startX, startY, tmp.Width, maxHeight); return tmp.Clone(sourceRectangle, PixelFormat.DontCare); } else { // height is smaller and therefore needs to be decreased double ratio = (double)image.Width / image.Height; height = maxHeight; width = Convert.ToInt32((double)height * ratio); Bitmap tmp = new Bitmap(width, height, image.PixelFormat); Graphics newG = Graphics.FromImage(tmp); newG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; newG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; // Draw 3 times to prevent "black border" newG.DrawImage(image, 0, 0, tmp.Width, tmp.Height); newG.DrawImage(image, 0, 0, tmp.Width, tmp.Height); newG.DrawImage(image, 0, 0, tmp.Width, tmp.Height); newG.Dispose(); // Find out how many pixels need to be cropped startX = (int)System.Math.Floor((double)((tmp.Width - maxWidth) / 2)); Rectangle sourceRectangle = new Rectangle(startX, startY, maxWidth, height); return tmp.Clone(sourceRectangle, PixelFormat.DontCare); } } } private void photoZipper_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { MessageBox.Show("Goed nieuws, de foto's zijn ingepakt en opgeslagen op uw bureaublad als \"ingepakte_fotos.zip\"." + System.Environment.NewLine + "U kunt nu verder met uw Manager.", "Klaar", MessageBoxButtons.OK, MessageBoxIcon.Information); Application.Exit(); } } }