drawn an rectangle on the image using picture box.

quires

1. when tried to zoom image the drawn rectangles needs to be placed on the drawn area.
2. Also draw another rectangle (in zoomed mode).
3. when i zoomed out the rectangle needs to resized.

How can i achieve this.

I achieved this by using graphics.drawrectangle but i don't want to draw rectangle on the image because it's stay permanently on the image (like to cahnge size when user likes).


Tried the below logic (for Xand y Co-ordinates) and it varies from point to point on the Image.

//used in zoomIn menthod
rect1 = new Rectangle(rectangles[c].X+((pictureBox1.Width/rectangles[c].Height)+(pictureBox1.Width/100)),rectangles[c].Y+((pictureBox1.Height/rectangles[c].Width)), rectangles[c].Width, rectangles[c].Height);
                rectangles.RemoveAt(c);
                rectangles.Insert(c, rect1);
                rect = new Rectangle(0, 0, 0, 0);

Please help on this......

//getting size of picture box in sz1
public void ZoomIn()
        {
            //pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
            if (sz1.Width >= 800 * 6)
                MessageBox.Show("Max ZoomIn");
            else
            {
                sz1.Width += 100;
                sz1.Height += 100;
                pictureBox1.Size = sz1;
                
                pictureBox1.Invalidate();
            }
            

        }

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            
                

                if (mybitmap == null)
                {
                    mybitmap = new Bitmap(pictureBox1.Image.Width, pictureBox1.Image.Height);
                    mybitmap.SetResolution(300, 300);
                }


                    rect = new Rectangle(e.X, e.Y, 0, 0);
                    pictureBox1.Invalidate();

           

        }




private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            

                if (mybitmap == null)
                {
                    return;
                }

                
                    
                    using (Pen pen = new Pen(Color.Green, 2))
                    {
                       
                        
                            foreach (Rectangle r in rectangles)
                            {
                                e.Graphics.DrawRectangle(pen, r);

                                e.Graphics.DrawString(lab[c].ToString(), new Font(lab[c].ToString(), 8F), new SolidBrush(label1.ForeColor), r);
                                

                            }

                            
                    }
       
        }

Recommended Answers

All 14 Replies

I'm no expert in the draw process but from what little I know the standard Graphics.Draw methods tend to be 'static' in their positioning. In order to achieve a "zoom" effect I would do something like the following (pseudocode not C# code cus I don't know the processes required per-se)

  1. Determine mid-point of existing rectangle ~ ((x2(right) - x1(left))/2) = xMid, ((y2(bottom) - y1(top))/2) = yMid
  2. Determine zoom ratio (2:1, etc)
  3. Convert xLength (x2(right)-x1(left)) * ratio
  4. Convert yLength (y2(bottom) - y1(top)) * ratio
  5. Find new x positions xMid +- (xLength/2) = newXTop & newXBottom
  6. Find new y positions yMid +- (yLength/2) = newYLeft & newYRight
  7. Draw new zoomed rectangle

Based on this process you determine the existing center point and "zoom" accordingly to the same center point on your new ratio.

Hope that helps :) It's been a while since I used draw methods so I'm sorry I can't provide actual code for the scenario.

Thanks for your answer. please clear my doubts

say my rectangle value(150, 200, 25, 25) and increasing picture width and height by 100 so my ratio be
ratio = (new width/old width);
ratio1 = (new height/old height);


xMid = ((150+25)- 150)/2);
yMid = ((200+25)- 200/2);
xLength = xMid* ratio;
yLength = ymid* ratio1;

cant get 5 and 6 step...

Please clari on this....

Well my method works best with a consistant overall ratio change (ie: you double the display size therefor ratio = 2:1 or shrink to 2/3 size giving ratio of 2:3)

With an example of 2:1 (doubling) I would do the following

  1. Determine mid-point of existing rectangle ~ ((x2(right) - x1(left))/2) + x1 = xMid - ((150-25)/2)+25) = 87.5, ((y2(bottom) - y1(top))/2) + y1 = yMid = ((200-25)/2)+25) = 112.5
  2. Determine zoom ratio (2:1)
  3. Convert xLength (150 - 25) * 2:1 = 250
  4. Convert yLength (200 - 25) * 2:1 = 350
  5. Find new x positions (87.5 * 2:1) = 175 +- (250/2) = 50 & 300 (forgot to adjust mid-point for 2:1 ratio change as well, did it on the fly here)
  6. Find new y positions (112.5 * 2:1) = 225 +- (350/2) = 50 & 400

Hope that helps somewhat. In the end you end up with your original rectangle at (150, 200, 25, 25) your 2:1 rectangle (based on doubling display size as well which displaces the center mark to a new position in the process) at (300, 400, 50, 50). While it may seem the matter is as simple as doubling all the numbers the basic formula can be used to replicate the ratio change as well as insuring visual symetry in the center point of the shape.

In situations where you want to zoom the shape but not the container/display you can use all the steps above but omit the ratio conversion of the center point to allow conversion of the dimensions of the shape around the same center point as the original. ie: you want to shrink the rectangle to 2/3 size but keep it centered on the same point as the original rectangle without changing the display width/height.

So to expand on the above example, to shrink by 2/3 but keep same container/display dimensions...

  1. Determine mid-point of existing rectangle ~ ((x2(right) - x1(left))/2) + x1 = xMid - ((150-25)/2)+25) = 87.5, ((y2(bottom) - y1(top))/2) + y1 = yMid = ((200-25)/2)+25) = 112.5
  2. Determine zoom ratio (2:3)
  3. Convert xLength (150 - 25) * 2:3 = 83.333
  4. Convert yLength (200 - 25) * 2:3 = 183.333
  5. Find new x positions 87.5 +- (83.333/2) = 45.833 (closest full pixel is 46) & 129.167 (closest full pixel is 129)
  6. Find new y positions 112.5 +- (350/2) = 20.833 (closest full pixel is 21) & 204.167 (closest full pixel is 204)

Completed new rect would be (129, 204, 46, 21).

When you zoom the image are you resizing the picture box to fit or is part of the image hidden outside the container?

resizing picture box to fit

If you are resizing the picturebox then its fairly simple to resize the box:

public partial class Form1 : Form
{
        public Form1()
        {
            InitializeComponent();

            //set initial value for image size
            OldImage = picBoxImage.Size;
        }

        //rectangle to be painted
        RectangleF rect = new RectangleF(150, 200, 25, 25);

        //track image size
        Size OldImage;

        //method to resize rectangle
        private void ScaleRectangle()
        {
            //find scale of change by comparing current size with size before zooming
            float Scale = picBoxImage.Width / OldImage.Width;

            //apply scale to rectangle
            rect.X *= Scale;
            rect.Y *= Scale;
            rect.Width *= Scale;
            rect.Height *= Scale;
        }

        private void picBoxImage_Paint(object sender, PaintEventArgs e)
        {
            //paint rectangle every time image is repainted
            e.Graphics.DrawRectangle(new Pen(Brushes.Black), rect.X, rect.Y, rect.Width, rect.Height);
        }

        //button to test resize
        private void button2_Click(object sender, EventArgs e)
        {
            //log current image size before zooming
            OldImage = new Size(picBoxImage.Width, picBoxImage.Height);

            picBoxImage.Height *= 2;
            picBoxImage.Width *= 2;

            //scale rectangle after altering image
            ScaleRectangle();
        }
}
commented: Well played! :twisted: +1

as lusipher pointed out, if the centre of the image moves you need to move the box equally. But if all you do is resize the image then you just rescale the box too :)

:twisted: My method was more of a "theory-in-practice" method but ryshad's got the point of it and I like his method as more simplistic to implement.

I wrote an app a short while ago that allowed a user to zoom in and out of an aerial photo and draw boxes on it which then acted like buttons. The user drawn control thing was fun to do, but i got plenty of practice at the scale/translate transformation concept :p

thanks Lusiphur and Ryshad and great it's works as expected.

if increase the scale by 200 (say old picture width is 800 and increase by 200) then what will be the ratio.

Well that's not quite what I meant by ratio but...

If your width was 800 and you increase it by 200 then your new ratio is 10:8 of the original or 5:4 <--> (800+200):800.

Edit: That's an increase of 1.25x the original image if you don't like the 5:4 way :twisted:

Hope that helps :) Don't forget to mark solved once your issue is resolved.

my float to int convertion is incorrect and now i have corrected that.

once again thanks Lusiphur and Ryshad

Float to int convertion is incorrect and now i corrected that.

Once again thanks Lusiphur and Ryshad

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.