Solved

Select area in PictureBox

Posted on 2006-11-05
2
2,097 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article introduced a TextBox that supports transparent background.   Introduction TextBox is the most widely used control component in GUI design. Most GUI controls do not support transparent background and more or less do not have the…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This is a high-level webinar that covers the history of enterprise open source database use. It addresses both the advantages companies see in using open source database technologies, as well as the fears and reservations they might have. In this…
This video Micro Tutorial shows how to password-protect PDF files with free software. Many software products can do this, such as Adobe Acrobat (but not Adobe Reader), Nuance PaperPort, and Nuance Power PDF, but they are not free products. This vide…

691 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