0

I have a PictureBox inside a Panel, and I have implemented the zoom function with a TrackBar.

When I increase (or decrease) the PictureBox, the position of the image remain fixed on the left side of the PictureBox. See the example to better understand the problem.

enter image description here

What I want is the possibility to relocate the image compared to the center of the Panel. See the following example

enter image description here

For example I tried to define the PictureBox X origin in this way:

  1. before the zoom I calculate the distance (Δdx) between the origin of the PictureBox (x0) and the center of the Panel (x1).
  2. I increase the distance with the zoom factor (Δdx').
  3. I calculate the new origin of the image (x0') as x1 - Δdx'

I do the same with Y and I define the new PictureBox location with x0' and y0'.

Here the code:

// new image width after the zoom
double width = pbImg.Image.Width + (pbImg.Image.Width * trackbar.Value / 100);

// new image height after the zoom
double height = pbImg.Image.Height + (pbImg.Image.Height * trackbar.Value / 100);

// panel center
int cX = panel.Width / 2;
int cY = panel.Height / 2;

// actual origin for the picturebox
int imgX = pbImg.Location.X;
int imgY = pbImg.Location.Y;

// distance the panel center and the picturebox origin
int distFromXc = cX - imgX;
int distFromYc = cY - imgY;

// new distance with zoom factor
distFromXc = distFromXc + (distFromXc * trackbar.Value / 100);
distFromYc = distFromYc + (distFromYc * trackbar.Value / 100);

// new origin point for the picturebox
int pbX = (cX - distFromXc);
int pbY = (cY - distFromYc);

// new dimension for the picturebox
pbImg.Size = new Size(Convert.ToInt32(width), Convert.ToInt32(height));

// relocate picturebox
Point p = new Point(pbX, pbY);
pbImg.Location = p;

I tried to modify this C# code, but I’m not familiar with it.

In my case I want to manage the Picturebox and the image inside it as the same object (if it’s possible).

What I want is the possibility to increase (or decrease) the Picturebox (and the image inside) but I want the Picturebox to stay centered where it currently is.

The SizeMode of the picture is StretchImage.

The Trackbar has 0% as he minimum value and 100% as the maximum. The size of the Picturebox, and the image isnside, can be variable, I receive the images from another software.

A zoomed Picturebox can be bigger than Panel, but it’s not a problem, because I can move it.

The problems are the following: 1. If i use the code I wrote above, the reposition seems to work, but the Picturebox isn’t resized. 2. If I use a fixed value for the origin of the Picturebox (for example Point p = new Point(50, 50)), the resize works but obviously the position of the Picturebox is fixed.

  • imgY.Location doesn't make sense, please post the real code you are using. – Hans Passant Jun 11 '19 at 14:01
  • there was an error, I corrected it. This is the function that i'm using –  Jun 11 '19 at 14:15
  • Thre's some confusion in the description of the process, here. It's not clear if you want to resize/reposition the PictureBox, the Image inside it or both. Can you at least specify what's the SizeMode of the PictureBox? The math involved in keeping a rectangle in the middle of another, no matter what the size of the two, is quite simple. – Jimi Jun 11 '19 at 17:26
  • @Jimi I edited my question, I hope it’s more clear this time –  Jun 11 '19 at 20:50
  • Missing parts: what are the TrackBar min and max values and what do these represent? A percentage, where `100` equals to... what? The size of the container? The actual size of the Image? Can the value be to more than 100%, in this case? Or the TrackBar values represent a size in pixels? The images you posted may help, but the implementation details are more important, since you're asking for help in the implementation of a method. – Jimi Jun 11 '19 at 21:04

2 Answers2

0

This is because you are changing the size of the picturebox and not the size of the image within it. To ensure an image matches the size of the picture box ensure you set the stretchimage sizemode

pbImg.SizeMode = PictureBoxSizeMode.StretchImage

to get it working you could add this line just before you change the size of the picture box, however i recommend setting this on picturebox during its creation.

Refer to : Fit Image into PictureBox

S_BatMan
  • 505
  • 6
  • 13
  • I did as you told me, but nothing is changed. Here the code this.pbImg.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; –  Jun 11 '19 at 13:22
  • then i suggest you provide a wider example of your code that that provided above – S_BatMan Jun 11 '19 at 13:22
0

If you want the PictureBox to stay centered where it currently is, and only expand or deflate "in place", then try something like this:

double width = pbImg.Width * trackbar.Value / 100;
double height = pbImg.Height * trackbar.Value / 100;
Rectangle rc = pbImg.Bounds;
rc.Inflate((int)((width - pbImg.Width) / 2), (int)((height - pbImg.Height) / 2));
pbImg.Bounds = rc;

Note that this is all based on the size of the PictureBox itself, NOT the Image within. Not sure what SizeMode you have set for the PB...

enter image description here

---------- EDIT ----------

I'm using StretchImage as SizeMode. Is possible to have the same behavior but without the button? When I move the cursor from left to right the Pb increase and decrease from right to left – Scarj

Of course. Put my code into the ValueChanged() and/or Scroll() events. - Idle_Mind

The original post works off the current size of the PictureBox. You might want to store the original Bounds() of the PB (maybe in the Tag() property) and then always compute the new size based on that instead.

Here's an example of that:

private void Form1_Load(object sender, EventArgs e)
{
    pbImg.Tag = pbImg.Bounds;
}

private void button1_Click(object sender, EventArgs e)
{

}

private void trackBar1_Scroll(object sender, EventArgs e)
{
    ZoomPB();
}

private void trackBar1_ValueChanged(object sender, EventArgs e)
{
    ZoomPB();
}

private void ZoomPB()
{
    Rectangle rc = (Rectangle)pbImg.Tag;
    double width = rc.Width * trackbar.Value / 100;
    double height = rc.Height * trackbar.Value / 100;
    rc.Inflate((int)((width - rc.Width) / 2), (int)((height - rc.Height) / 2));
    pbImg.Bounds = rc;
}

enter image description here

Idle_Mind
  • 38,363
  • 3
  • 29
  • 40
  • I'm using StretchImage as SizeMode. Is possible to have the same behavior but without the button? When I move the cursor from left to right the Pb increase and decrease from right to left –  Jun 12 '19 at 10:49
  • Of course. Put my code into the ValueChanged() and/or Scroll() events. – Idle_Mind Jun 12 '19 at 12:19
  • I edited my post with an example of not using the button. – Idle_Mind Jun 12 '19 at 13:06
  • I tried, but in this way when I increase (or decrease), the picturebox is always relocated at the center of the Panel. My picturebox can be bigger than the panel, I already have implemented the possibility to move the Picturebox. –  Jun 12 '19 at 13:25
  • With my code, the PB will stay centered wherever it was. The size will increase or decrease around the center point. Are you experiencing different behavior with my code? – Idle_Mind Jun 12 '19 at 21:09