Solved

Select area in PictureBox

Posted on 2006-11-05
2
2,019 Views
Last Modified: 2008-01-09
Hi Experts,

Here is my UserControl:

/* Title:
 * PictureBox with zoom and scroll functionallity
 */

#region Usings

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

#endregion

namespace PictureBoxCtrl
{
      /// <summary>
      /// Summary for the PictureBox Ctrl
      /// </summary>
      public class PictureBox : System.Windows.Forms.UserControl
      {
            #region Members

            public System.Windows.Forms.PictureBox PicBox;
            private System.Windows.Forms.Panel OuterPanel;
            private System.ComponentModel.Container components = null;
            private string m_sPicName = "";

        private bool down;
        private Point start;
        private Rectangle selection = Rectangle.Empty;

            #endregion

            #region Constants

            private double ZOOMFACTOR = 1.25;      // = 25% smaller or larger
            private int MINMAX = 5;                        // 5 times bigger or smaller than the ctrl

            #endregion

            #region Designer generated code

            private void InitializeComponent()
            {
                  this.PicBox = new System.Windows.Forms.PictureBox();
                  this.OuterPanel = new System.Windows.Forms.Panel();
                  this.OuterPanel.SuspendLayout();
                  this.SuspendLayout();
                  //
                  // PicBox
                  //
                  this.PicBox.Location = new System.Drawing.Point(0, 0);
                  this.PicBox.Name = "PicBox";
                  this.PicBox.Size = new System.Drawing.Size(150, 140);
                  this.PicBox.TabIndex = 3;
                  this.PicBox.TabStop = false;
                  //
                  // OuterPanel
                  //
                  this.OuterPanel.AutoScroll = true;
                  this.OuterPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
                  this.OuterPanel.Controls.Add(this.PicBox);
                  this.OuterPanel.Dock = System.Windows.Forms.DockStyle.Fill;
                  this.OuterPanel.Location = new System.Drawing.Point(0, 0);
                  this.OuterPanel.Name = "OuterPanel";
                  this.OuterPanel.Size = new System.Drawing.Size(210, 190);
                  this.OuterPanel.TabIndex = 4;
                  //
                  // PictureBox
                  //
                  this.Controls.Add(this.OuterPanel);
                  this.Name = "PictureBox";
                  this.Size = new System.Drawing.Size(210, 190);
                  this.OuterPanel.ResumeLayout(false);
                  this.ResumeLayout(false);

            }
            #endregion

            #region Constructors

            public PictureBox()
            {
                  InitializeComponent ();
                  InitCtrl ();      // my special settings for the ctrl
            }

            #endregion

            #region Properties

            /// <summary>
            /// Property to select the picture which is displayed in the picturebox. If the
            /// file doesn´t exist or we receive an exception, the picturebox displays
            /// a red cross.
            /// </summary>
            /// <value>Complete filename of the picture, including path information</value>
            /// <remarks>Supported fileformat: *.gif, *.tif, *.jpg, *.bmp</remarks>
            [ Browsable ( false ) ]
            public string Picture
            {
                  get { return m_sPicName; }
                  set
                  {
                        if ( null != value )
                        {
                              if ( System.IO.File.Exists ( value ) )
                              {
                                    try
                                    {
                                          PicBox.Image = Image.FromFile ( value );
                                          m_sPicName = value;
                                    }
                                    catch ( OutOfMemoryException ex )
                                    {
                                          RedCross ();
                                    }
                              }
                              else
                              {                        
                                    RedCross ();
                              }
                        }
                  }
            }

            /// <summary>
            /// Set the frametype of the picturbox
            /// </summary>
            [ Browsable ( false ) ]
            public BorderStyle Border
            {
                  get { return OuterPanel.BorderStyle; }
                  set { OuterPanel.BorderStyle = value; }
            }

        public Rectangle Selection
        {
            get { return selection; }
        }
      

            #endregion

            #region Other Methods

            /// <summary>
            /// Special settings for the picturebox ctrl
            /// </summary>
            private void InitCtrl ()
            {
                  PicBox.SizeMode = PictureBoxSizeMode.StretchImage;
            PicBox.Location = new Point ( 0, 0 );
            PicBox.SizeMode = PictureBoxSizeMode.AutoSize;
                  OuterPanel.Dock = DockStyle.Fill;
                  //OuterPanel.Cursor = System.Windows.Forms.Cursors.NoMove2D;
                  OuterPanel.AutoScroll = true;
                  OuterPanel.MouseEnter += new EventHandler(PicBox_MouseEnter);
                  PicBox.MouseEnter += new EventHandler(PicBox_MouseEnter);
                  OuterPanel.MouseWheel += new MouseEventHandler(PicBox_MouseWheel);
            PicBox.MouseDown += new MouseEventHandler(PicBox_MouseDown);
            PicBox.MouseMove += new MouseEventHandler(PicBox_MouseMove);
            PicBox.MouseUp += new MouseEventHandler(PicBox_MouseUp);
            }

        void PicBox_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                WindowsApplicationPlayer.NativeWIN32.InvalidateRect(IntPtr.Zero, IntPtr.Zero, true);
                //ControlPaint.DrawReversibleFrame(selection, this.BackColor, FrameStyle.Dashed);
                down = true;
                selection = Rectangle.Empty;
                ControlPaint.DrawReversibleFrame(selection, this.BackColor, FrameStyle.Dashed);
                start = this.PointToScreen(new Point(e.X, e.Y));
            }
        }

        void PicBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (down)
            {
                ControlPaint.DrawReversibleFrame(selection, this.BackColor, FrameStyle.Dashed);

                Point end = this.PointToScreen(new Point(e.X, e.Y));
                selection = new Rectangle(start.X, start.Y, end.X - start.X, end.Y - start.Y);

                ControlPaint.DrawReversibleFrame(selection, this.BackColor, FrameStyle.Dashed);
            }
        }

        void PicBox_MouseUp(object sender, MouseEventArgs e)
        {
            if (down)
            {
                //ControlPaint.DrawReversibleFrame(selection, this.BackColor, FrameStyle.Dashed);
                down = false;
            }
        }
            /// <summary>
            /// Create a simple red cross as a bitmap and display it in the picturebox
            /// </summary>
            private void RedCross ()
            {
                  Bitmap bmp = new Bitmap ( OuterPanel.Width, OuterPanel.Height, System.Drawing.Imaging.PixelFormat.Format16bppRgb555 );
                  Graphics gr;
                  gr = Graphics.FromImage ( bmp );
                  Pen pencil = new Pen ( Color.Red, 5 );
                  gr.DrawLine ( pencil, 0, 0, OuterPanel.Width, OuterPanel.Height );
                  gr.DrawLine ( pencil, 0, OuterPanel.Height, OuterPanel.Width, 0  );
                  PicBox.Image = bmp;
                  gr.Dispose ();
            }

            #endregion

            #region Zooming Methods

            /// <summary>
            /// Make the PictureBox dimensions larger to effect the Zoom.
            /// </summary>
            /// <remarks>Maximum 5 times bigger</remarks>
            private void ZoomIn()
            {
            if ( ( PicBox.Width < ( MINMAX * OuterPanel.Width ) ) &&
                        ( PicBox.Height < ( MINMAX * OuterPanel.Height ) ) )
                  {
                        PicBox.Width = Convert.ToInt32 ( PicBox.Width * ZOOMFACTOR );
                        PicBox.Height = Convert.ToInt32 ( PicBox.Height * ZOOMFACTOR );
                        PicBox.SizeMode = PictureBoxSizeMode.StretchImage;
                  }
            }

            /// <summary>
            /// Make the PictureBox dimensions smaller to effect the Zoom.
            /// </summary>
            /// <remarks>Minimum 5 times smaller</remarks>
            private void ZoomOut()
            {
            if ( ( PicBox.Width > ( OuterPanel.Width / MINMAX ) ) &&
                        ( PicBox.Height > ( OuterPanel.Height / MINMAX ) ) )
                  {
                        PicBox.SizeMode = PictureBoxSizeMode.StretchImage;
                        PicBox.Width = Convert.ToInt32 ( PicBox.Width / ZOOMFACTOR );
                        PicBox.Height = Convert.ToInt32 ( PicBox.Height / ZOOMFACTOR );
                  }            
            }

            #endregion

            #region Mouse events

            /// <summary>
            /// We use the mousewheel to zoom the picture in or out
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void PicBox_MouseWheel(object sender, MouseEventArgs e)
            {
            //ControlPaint.DrawReversibleFrame(selection, this.BackColor, FrameStyle.Dashed);
            //if ( e.Delta < 0 )
            //{
            //    ZoomIn ();
            //}
            //else
            //{
            //    ZoomOut ();
            //}
            }

            /// <summary>
            /// Make sure that the PicBox have the focus, otherwise it doesn´t receive
            /// mousewheel events !.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void PicBox_MouseEnter(object sender, EventArgs e)
            {
                  if ( PicBox.Focused == false )
                  {
                        PicBox.Focus ();
                  }
            }

            #endregion

            #region Disposing

            /// <summary>
            /// </summary>
            protected override void Dispose( bool disposing )
            {
                  if( disposing )
                  {
                        if( components != null )
                              components.Dispose();
                  }
                  base.Dispose( disposing );
            }

            #endregion
      }
}

The problem is when I select an area of my image:
if I don't use the scrollbars, the rectangle is correctly drawn.
if I move scrollbars up or down, then the rectangle is drawn to a wrong location (often outside of the picture and very far from the mouse).

Thanks in advance for your help.
0
Comment
Question by:noulouk
2 Comments
 
LVL 48

Accepted Solution

by:
AlexFM earned 500 total points
ID: 17876023
Try this:

void PicBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (down)
            {
                ControlPaint.DrawReversibleFrame(selection, this.BackColor, FrameStyle.Dashed);

                Point end = this.PointToScreen(new Point(e.X + outerPanel.AutoScrollPosition.X, e.Y + outerPanel.AutoScrollPosition.Y));  // or "-", I don't remember exactly
                selection = new Rectangle(start.X, start.Y, end.X - start.X, end.Y - start.Y);

                ControlPaint.DrawReversibleFrame(selection, this.BackColor, FrameStyle.Dashed);
            }
        }

The same correction in PicBox_MouseDown for start point.
0
 
LVL 9

Author Comment

by:noulouk
ID: 17876959
Perfect thank you.
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Bit flags and bit flag manipulation is perhaps one of the most underrated strategies in programming, likely because most programmers developing in high-level languages rely too much on the high-level features, and forget about the low-level ones. Th…
Article by: Najam
Having new technologies does not mean they will completely replace old components.  Recently I had to create WCF that will be called by VB6 component.  Here I will describe what steps one should follow while doing so, please feel free to post any qu…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now