Sourcecode - BitmapSelect

Download BitmapSelect.cs

////////////////////////////////////////////////
////             BitmapSelect               ////
////  Version 1.0.0               28.05.04  ////
////////////////////////////////////////////////
// 
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// 
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace Plugin.UI.Windows
{
	/// <summary>
	/// W�hlt einen Ausschnitt aus einem Bild aus
	/// </summary>
	public class BitmapSelect : System.Windows.Forms.Form
	{
		#region Komponenten
		private System.Windows.Forms.Button buttonOK;
		private System.Windows.Forms.Button buttonAbort;
		private System.Windows.Forms.Panel bottomPanel;
		private System.Windows.Forms.PictureBox pic;
		/// <summary>
		/// Erforderliche Designervariable.
		/// </summary>
		private System.ComponentModel.Container components = null;
		#endregion
		
		Bitmap original;
		
		#region SelectedRange
		Rectangle sel;
		
		/// <summary>
		/// Das gew�hlte Rechteck
		/// </summary>
		public Rectangle SelectedRect
		{
			get 
			{
				if (halbiert) 
					return new Rectangle(sel.X * 2, sel.Y * 2, sel.Width * 2, sel.Height * 2);
				else
					return sel;
			}
		}
		
		/// <summary>
		/// Ruft das ausgew�hlte Bild ab. Kann null oder das Original-Bild zur�ckgeben,
		/// wenn nichts bzw. alles gew�hlt wurde.
		/// </summary>
		public Bitmap GetSelectedBitmap() 
		{
			Rectangle sel = SelectedRect;
			if (sel.Width == 0 || sel.Height == 0) return null;
			if (sel.X == 0 && sel.Y == 0 && sel.Width >= original.Width && sel.Height >= original.Height)
			{
				return original;
			}
			Bitmap bmp = new Bitmap(sel.Width, sel.Height);
			for(int x = 0; x < sel.Width; x++) 
			{
				for(int y = 0; y < sel.Height; y++)
				{
					bmp.SetPixel(x, y, original.GetPixel(sel.X + x, sel.Y + y));
				}
			}
			return bmp;
		}
		#endregion
		
		#region Halbiert
		bool halbiert = false;
		
		/// <summary>Gibt an, ob die Gr��e des Bildes f�r die Anzeige halbiert wurde.</summary>
		public bool Halbiert 
		{
			get 
			{
				return halbiert;
			}
		}
		#endregion
		
		#region Konstruktor
		/// <summary>
		/// Erzeugt einen neuen Ausschnitts-W�hler f�r das angegebene Bild, der die
		/// Halbierung der Gr��e erlaubt.
		/// </summary>
		public BitmapSelect(Bitmap bmp) : this(bmp, true)
		{
		}
		
		/// <summary>
		/// Erzeugt einen neuen Ausschnitts-W�hler f�r das angegebene Bild.
		/// </summary>
		public BitmapSelect(Bitmap bmp, bool allowHalfSize)
		{
			//
			// Erforderlich f�r die Windows Form-Designerunterst�tzung
			//
			InitializeComponent();
			
			original = bmp;

			if (allowHalfSize) 
			{
				Rectangle workingArea = Screen.GetWorkingArea(this);
				if (workingArea.Width - 50 < bmp.Width ||
					workingArea.Height - 70 - bottomPanel.Height < bmp.Height) 
				{
					halbiert = true;
					bmp = new Bitmap(bmp, bmp.Width / 2, bmp.Height / 2);
				}
			}
			
			ClientSize = new Size(bmp.Width, bmp.Height + bottomPanel.Height);
			base.CenterToScreen();
			CreatePens();
			DialogResult = DialogResult.Cancel;
			pic.BackgroundImage = bmp;
			sel = new Rectangle(0, 0, bmp.Width, bmp.Height);
		}
		#endregion
		
		#region Dispose
		/// <summary>
		/// Die verwendeten Ressourcen bereinigen.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				DisposePens();
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}
		#endregion
		
		#region Vom Windows Form-Designer generierter Code
		/// <summary>
		/// Erforderliche Methode f�r die Designerunterst�tzung. 
		/// Der Inhalt der Methode darf nicht mit dem Code-Editor ge�ndert werden.
		/// </summary>
		private void InitializeComponent()
		{
			this.bottomPanel = new System.Windows.Forms.Panel();
			this.buttonAbort = new System.Windows.Forms.Button();
			this.buttonOK = new System.Windows.Forms.Button();
			this.pic = new System.Windows.Forms.PictureBox();
			this.bottomPanel.SuspendLayout();
			this.SuspendLayout();
			// 
			// bottomPanel
			// 
			this.bottomPanel.Controls.Add(this.buttonAbort);
			this.bottomPanel.Controls.Add(this.buttonOK);
			this.bottomPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
			this.bottomPanel.Location = new System.Drawing.Point(0, 226);
			this.bottomPanel.Name = "bottomPanel";
			this.bottomPanel.Size = new System.Drawing.Size(292, 40);
			this.bottomPanel.TabIndex = 0;
			// 
			// buttonAbort
			// 
			this.buttonAbort.Anchor = System.Windows.Forms.AnchorStyles.Right;
			this.buttonAbort.DialogResult = System.Windows.Forms.DialogResult.Cancel;
			this.buttonAbort.FlatStyle = System.Windows.Forms.FlatStyle.System;
			this.buttonAbort.Location = new System.Drawing.Point(120, 8);
			this.buttonAbort.Name = "buttonAbort";
			this.buttonAbort.Size = new System.Drawing.Size(72, 24);
			this.buttonAbort.TabIndex = 1;
			this.buttonAbort.Text = "Abbruch";
			this.buttonAbort.Click += new System.EventHandler(this.buttonAbort_Click);
			// 
			// buttonOK
			// 
			this.buttonOK.Anchor = System.Windows.Forms.AnchorStyles.Right;
			this.buttonOK.FlatStyle = System.Windows.Forms.FlatStyle.System;
			this.buttonOK.Location = new System.Drawing.Point(208, 8);
			this.buttonOK.Name = "buttonOK";
			this.buttonOK.Size = new System.Drawing.Size(72, 24);
			this.buttonOK.TabIndex = 0;
			this.buttonOK.Text = "OK";
			this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click);
			// 
			// pic
			// 
			this.pic.Dock = System.Windows.Forms.DockStyle.Fill;
			this.pic.Location = new System.Drawing.Point(0, 0);
			this.pic.Name = "pic";
			this.pic.Size = new System.Drawing.Size(292, 226);
			this.pic.TabIndex = 1;
			this.pic.TabStop = false;
			this.pic.Paint += new System.Windows.Forms.PaintEventHandler(this.pic_Paint);
			this.pic.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pic_MouseUp);
			this.pic.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pic_MouseMove);
			this.pic.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pic_MouseDown);
			// 
			// BitmapSelect
			// 
			this.AcceptButton = this.buttonOK;
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.CancelButton = this.buttonAbort;
			this.ClientSize = new System.Drawing.Size(292, 266);
			this.Controls.Add(this.pic);
			this.Controls.Add(this.bottomPanel);
			this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
			this.Name = "BitmapSelect";
			this.Text = "Bildausschnitt-Wahl";
			this.bottomPanel.ResumeLayout(false);
			this.ResumeLayout(false);

		}
		#endregion
		
		#region Buttons
		private void buttonAbort_Click(object sender, System.EventArgs e)
		{
			Close();
		}

		private void buttonOK_Click(object sender, System.EventArgs e)
		{
			DialogResult = DialogResult.OK;
			Close();
		}
		#endregion
		
		#region static Select
		/// <summary>W�hlt einen Ausschnitt aus einem Bild aus.</summary>
		/// <param name="bmp">Das Bild, aus dem ein Ausschnitt gew�hlt werden soll.</param>
		/// <returns>Der gew�hlte Ausschnitt</returns>
		/// <remarks>Diese Funktion gibt, wenn der Benutzer keinen Ausschnitt w�hlt, das
		/// Original-Bild zur�ck. Rufen Sie daher nicht Dispose auf dem Originalbild auf!</remarks>
		public static Bitmap Select(Bitmap bmp)
		{
			Plugin.UI.Windows.BitmapSelect sel = new Plugin.UI.Windows.BitmapSelect(bmp);
			DialogResult res = sel.ShowDialog();
			if (res != DialogResult.OK) return null;
			return sel.GetSelectedBitmap();
		}
		#endregion
		
		#region Zeichnen
		Pen red;

		void CreatePens() 
		{
			red = new Pen(Color.Red);
			red.DashStyle = DashStyle.Dash;
		}

		void DisposePens() 
		{
			red.Dispose();
		}
		
		Point start;
		bool mouseDown = false;
        
		private void pic_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Left)
			{
				mouseDown = true;
				start = new Point(e.X, e.Y);
				sel = new Rectangle(start, new Size(0, 0));
			}
		}

		private void pic_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if (!mouseDown) return;
			int x = e.X;
			int y = e.Y;
			if (x < 0) x = 0;
			if (y < 0) y = 0;
			if (x >= pic.Width) x = pic.Width - 1;
			if (y >= pic.Height) y = pic.Height - 1;
			Point lo = new Point(Math.Min(start.X, x), Math.Min(start.Y, y));
			Point ru = new Point(Math.Max(start.X, x), Math.Max(start.Y, y));
			sel = new Rectangle(lo.X, lo.Y, ru.X - lo.X, ru.Y - lo.Y);
			pic.Invalidate();
		}

		private void pic_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Left)
			{
				mouseDown = false;
				pic.Invalidate();
			}
		}
        
		private void pic_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
		{
			Graphics g = e.Graphics;
			g.DrawRectangle(red, sel);
		}
		#endregion
	}
}