using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.IO;
using System.Drawing.Imaging;

namespace CropImage
{
    public partial class frm39CropImage : Form
    {
        public frm39CropImage()
        {
            InitializeComponent();
        }

        // The unmodified image.
        private Bitmap OriginalImage = null;

        // Load an image file.
        private void openMenuItem_Click(object sender, EventArgs e)
        {
            if (imageOpenFileDialog.ShowDialog() == DialogResult.OK)
            {
                OriginalImage = LoadBitmapUnlocked(imageOpenFileDialog.FileName);
                saveAsMenuItem.Enabled = true;
                imagePictureBox.Image = OriginalImage;
                imagePictureBox.Show();
            }
        }

        // Save the cropped result.
        private void saveAsMenuItem_Click(object sender, EventArgs e)
        {
            if (imageSaveFileDialog.ShowDialog() == DialogResult.OK)
            {
                SaveImage(OriginalImage, imageSaveFileDialog.FileName);
            }
        }

        // Exit.
        private void exitMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        // Load a bitmap without locking it.
        private Bitmap LoadBitmapUnlocked(string filename)
        {
            using (Bitmap bm = new Bitmap(filename))
            {
                return new Bitmap(bm);
            }
        }

        // Save the file with the appropriate format.
        public void SaveImage(Image image, string filename)
        {
            string extension = Path.GetExtension(filename);
            switch (extension.ToLower())
            {
                case ".bmp":
                    image.Save(filename, ImageFormat.Bmp);
                    break;
                case ".exif":
                    image.Save(filename, ImageFormat.Exif);
                    break;
                case ".gif":
                    image.Save(filename, ImageFormat.Gif);
                    break;
                case ".jpg":
                case ".jpeg":
                    image.Save(filename, ImageFormat.Jpeg);
                    break;
                case ".png":
                    image.Save(filename, ImageFormat.Png);
                    break;
                case ".tif":
                case ".tiff":
                    image.Save(filename, ImageFormat.Tiff);
                    break;
                default:
                    throw new NotSupportedException(
                        "Unknown file extension " + extension);
            }
        }

        // True when we're selecting a rectangle.
        private bool IsSelecting = false;

        // The drags starting point.
        private Point StartPoint;

        // Start selecting the rectangle.
        private void imagePictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            IsSelecting = true;

            // Copy the original image.
            OriginalImage = new Bitmap(imagePictureBox.Image);

            // Save the start point.
            StartPoint = e.Location;
        }

        // Continue selecting.
        private void imagePictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            // Do nothing it we're not selecting an area.
            if (!IsSelecting) return;

            // Make a Bitmap to display the selection rectangle.
            Bitmap bm = new Bitmap(OriginalImage);
            using (Graphics gr = Graphics.FromImage(bm))
            {
                // Draw the rectangle.
                Rectangle rect = GetRectangle(StartPoint, e.Location);
                using (Pen pen = new Pen(Color.Red, 3))
                {
                    gr.DrawRectangle(pen, rect);
                }
            }

            // Display the temporary bitmap.
            imagePictureBox.Image = bm;
        }

        // Finish selecting the area.
        private void imagePictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            // Do nothing it we're not selecting an area.
            if (!IsSelecting) return;
            IsSelecting = false;

            // Copy the selected part of the image.
            Rectangle rect = GetRectangle(StartPoint, e.Location);
            OriginalImage = ImagePiece(OriginalImage, rect);

            // Display the result.
            imagePictureBox.Image = OriginalImage;
        }

        // Return a Rectangle with the two points as opposite corners.
        private Rectangle GetRectangle(Point point1, Point point2)
        {
            int x = Math.Min(point1.X, point2.X);
            int y = Math.Min(point1.Y, point2.Y);
            int width = Math.Abs(point2.X - point1.X);
            int height = Math.Abs(point2.Y - point1.Y);
            return new Rectangle(x, y, width, height);
        }

        // Return a piece of an image.
        private Bitmap ImagePiece(Bitmap bm, Rectangle sourceRect)
        {
            // Intersect the rectangle with the Bitmap's bounds.
            Rectangle bmRect = new Rectangle(0, 0, bm.Width, bm.Height);
            sourceRect.Intersect(bmRect);

            // Make sure the result has a positive size.
            if ((sourceRect.Width < 1) || (sourceRect.Height < 1)) return null;

            Bitmap piece = new Bitmap(sourceRect.Width, sourceRect.Height);
            using (Graphics gr = Graphics.FromImage(piece))
            {
                Rectangle destRect = new Rectangle(0, 0,
                    sourceRect.Width, sourceRect.Height);
                gr.DrawImage(bm, destRect,
                    sourceRect, GraphicsUnit.Pixel);
            }
            return piece;
        }


        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.menuStrip1 = new System.Windows.Forms.MenuStrip();
            this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.openMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.saveAsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
            this.exitMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.imageOpenFileDialog = new System.Windows.Forms.OpenFileDialog();
            this.imageSaveFileDialog = new System.Windows.Forms.SaveFileDialog();
            this.imagePanel = new System.Windows.Forms.Panel();
            this.imagePictureBox = new System.Windows.Forms.PictureBox();
            this.menuStrip1.SuspendLayout();
            this.imagePanel.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.imagePictureBox)).BeginInit();
            this.SuspendLayout();
            // 
            // menuStrip1
            // 
            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.fileToolStripMenuItem});
            this.menuStrip1.Location = new System.Drawing.Point(0, 0);
            this.menuStrip1.Name = "menuStrip1";
            this.menuStrip1.Size = new System.Drawing.Size(384, 24);
            this.menuStrip1.TabIndex = 0;
            this.menuStrip1.Text = "menuStrip1";
            // 
            // fileToolStripMenuItem
            // 
            this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.openMenuItem,
            this.saveAsMenuItem,
            this.toolStripMenuItem1,
            this.exitMenuItem});
            this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
            this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
            this.fileToolStripMenuItem.Text = "&File";
            // 
            // openMenuItem
            // 
            this.openMenuItem.Name = "openMenuItem";
            this.openMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O)));
            this.openMenuItem.Size = new System.Drawing.Size(165, 22);
            this.openMenuItem.Text = "&Open...";
            this.openMenuItem.Click += new System.EventHandler(this.openMenuItem_Click);
            // 
            // saveAsMenuItem
            // 
            this.saveAsMenuItem.Enabled = false;
            this.saveAsMenuItem.Name = "saveAsMenuItem";
            this.saveAsMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A)));
            this.saveAsMenuItem.Size = new System.Drawing.Size(165, 22);
            this.saveAsMenuItem.Text = "Save &As...";
            this.saveAsMenuItem.Click += new System.EventHandler(this.saveAsMenuItem_Click);
            // 
            // toolStripMenuItem1
            // 
            this.toolStripMenuItem1.Name = "toolStripMenuItem1";
            this.toolStripMenuItem1.Size = new System.Drawing.Size(162, 6);
            // 
            // exitMenuItem
            // 
            this.exitMenuItem.Name = "exitMenuItem";
            this.exitMenuItem.Size = new System.Drawing.Size(165, 22);
            this.exitMenuItem.Text = "E&xit";
            this.exitMenuItem.Click += new System.EventHandler(this.exitMenuItem_Click);
            // 
            // imageOpenFileDialog
            // 
            this.imageOpenFileDialog.Filter = "Image files|*.bmp;*.jpg;*.gif;*.png;*.tif|All Files|*.*";
            // 
            // imageSaveFileDialog
            // 
            this.imageSaveFileDialog.DefaultExt = "png";
            this.imageSaveFileDialog.Filter = "Image files|*.bmp;*.jpg;*.gif;*.png;*.tif|All Files|*.*";
            // 
            // imagePanel
            // 
            this.imagePanel.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.imagePanel.AutoScroll = true;
            this.imagePanel.Controls.Add(this.imagePictureBox);
            this.imagePanel.Location = new System.Drawing.Point(12, 27);
            this.imagePanel.Name = "imagePanel";
            this.imagePanel.Size = new System.Drawing.Size(360, 222);
            this.imagePanel.TabIndex = 1;
            // 
            // imagePictureBox
            // 
            this.imagePictureBox.Cursor = System.Windows.Forms.Cursors.Cross;
            this.imagePictureBox.Location = new System.Drawing.Point(0, 0);
            this.imagePictureBox.Name = "imagePictureBox";
            this.imagePictureBox.Size = new System.Drawing.Size(16, 16);
            this.imagePictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
            this.imagePictureBox.TabIndex = 0;
            this.imagePictureBox.TabStop = false;
            this.imagePictureBox.Visible = false;
            this.imagePictureBox.MouseDown += new System.Windows.Forms.MouseEventHandler(this.imagePictureBox_MouseDown);
            this.imagePictureBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.imagePictureBox_MouseMove);
            this.imagePictureBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.imagePictureBox_MouseUp);
            // 
            // frm39CropImage
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(384, 261);
            this.Controls.Add(this.imagePanel);
            this.Controls.Add(this.menuStrip1);
            this.MainMenuStrip = this.menuStrip1;
            this.Name = "frm39CropImage";
            this.Text = "CropImage";
            this.menuStrip1.ResumeLayout(false);
            this.menuStrip1.PerformLayout();
            this.imagePanel.ResumeLayout(false);
            this.imagePanel.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)(this.imagePictureBox)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.MenuStrip menuStrip1;
        private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem openMenuItem;
        private System.Windows.Forms.ToolStripMenuItem saveAsMenuItem;
        private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
        private System.Windows.Forms.ToolStripMenuItem exitMenuItem;
        private System.Windows.Forms.OpenFileDialog imageOpenFileDialog;
        private System.Windows.Forms.SaveFileDialog imageSaveFileDialog;
        private System.Windows.Forms.Panel imagePanel;
        private System.Windows.Forms.PictureBox imagePictureBox;
    }
}