## Diamonddrake 397

I need to be able to take a point on an image and convert it into a point relative to a picturebox with the pictureSizeMode set to zoom

here is the code that the picturebox uses to scale and center the image

``````Size size = this.image.Size;
float num = Math.Min((float)(((float)base.ClientRectangle.Width) / ((float)size.Width)), (float)(((float)base.ClientRectangle.Height) / ((float)size.Height)));
rectangle.Width = (int)(size.Width * num);
rectangle.Height = (int)(size.Height * num);
rectangle.X = (base.ClientRectangle.Width - rectangle.Width) / 2;
rectangle.Y = (base.ClientRectangle.Height - rectangle.Height) / 2;
return rectangle;``````

I realize this returns a rectangle, but I need it to accept a point for example 0,0 on an image, if the image was tall it would be scaled by height so the the Y would stay 0 but if the image was say 359px wide and the picuture box was 417 pixles wide the point would go from 0,0 to 35,0.

I can get it to work so long as I use 0,0 but if I need other points I cant seem to make it happen. I'm not very good a geometry.

Any help would be appreciated.

## Geekitygeek 480

you need to reverse the transformation that the zoom applies. So start by removing the translation , then reverse the scale:

NB. just for clarity, as i know English isnt everyones first language, in this case i mean translation as 'a uniform movement without rotation' in line with the Graphics.TranslateTransform() method :)

``````//use mouse click rather than click event to access e.Location
private void pictureBox7_MouseClick(object sender, MouseEventArgs e)
{
Point imageLoc = ConvertToImage(e.Location, sender as PictureBox);

MessageBox.Show("Clicked: " + e.Location.ToString() + Environment.NewLine
+ "Image: " + imageLoc.ToString());
}

private Point ConvertToImage(Point clicked, PictureBox control)
{
//get size of original image
Size size = control.BackgroundImage.Size;
//get value of scale
float num = Math.Min((float)(((float)control.Width) / ((float)size.Width)), (float)(((float)control.Height) / ((float)size.Height)));

//scale size to calculate translation
size.Width = (int)(size.Width * num);
size.Height = (int)(size.Height * num);

//reverse translation
clicked.X -= (control.Width - size.Width) / 2;
clicked.Y -= (control.Height - size.Height) / 2;

//reverse scale
clicked.X = (int)(clicked.X / num);
clicked.Y = (int)(clicked.Y / num);

//return image coordinates
return clicked;
}``````

## Diamonddrake 397

Ryshad, That is some beautiful code. And I appreciate the time you put into it. But I am afraid I didn't describe my problem correctly. I am having trouble going from the actual Image coordinates to the Picturebox coordinates as zoomed. That is, exactly what your method there does, just reversed. I want it to accept an Image coordinate and return a zoomed picturebox coordinate.

I need it so that I can keep a selection rectangle from going outside of the image. I have most of the code worked out for the most part. But I'm having trouble with this. Thanks for the efforts you have put in.

and ddanbe, I glanced at that code snippet and I don't have time to run through it to see what it does right now, but I will later tonight. I would really like to get this control taken care of. Its for a little freeware app I am working on to make it easier to quickly and easily edit and mail pictures to your friends and family!

## Geekitygeek 480

Aah, i see what you need. Sorry, i assumed you were clicking on the zoomed image and needed to convert that back to the original image. Heres an overloaded method which will take a point/rectangle from the original image and convert it to match the zoomed image:

``````private Point ConvertToZoomed(Point image, PictureBox control)
{
//get size of original image
Size size = control.BackgroundImage.Size;

//get value of scale
float num = Math.Min((float)(((float)control.Width) / ((float)size.Width)), (float)(((float)control.Height) / ((float)size.Height)));

//scale size to calculate translation
size.Width = (int)(size.Width * num);
size.Height = (int)(size.Height * num);

//apply scale to Point
image.X = (int)(image.X * num);
image.Y = (int)(image.Y * num);

//apply translation to Point
image.X += (control.Width - size.Width) / 2;
image.Y += (control.Height - size.Height) / 2;

//return Zoomed Point
return image;

}

private Rectangle ConvertToZoomed(Rectangle selection, PictureBox control)
{
//get size of original image
Size size = control.BackgroundImage.Size;

//get value of scale
float num = Math.Min((float)(((float)control.Width) / ((float)size.Width)), (float)(((float)control.Height) / ((float)size.Height)));

//scale size to calculate translation
size.Width = (int)(size.Width * num);
size.Height = (int)(size.Height * num);

//apply scale to Selection
selection.X = (int)(selection.X * num);
selection.Y = (int)(selection.Y * num);
selection.Width = (int)(selection.Width * num);
selection.Height = (int)(selection.Height * num);

//apply translation to Selection
selection.X += (control.Width - size.Width) / 2;
selection.Y += (control.Height - size.Height) / 2;

//return Zoomed Selection
return selection;

}``````
commented: Great Code +2

## Diamonddrake 397

Thanks! I haven't tested it yet. But everything looks right. Thank you very much! I never did very well with geometry, and I had been struggling with this for a few hours before I decided I needed to ask for help. It looks so much simpler now, broken into commented steps.

Thanks again!