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.

Recommended Answers

All 5 Replies

Perhaps this snippet can be of help http://www.daniweb.com/code/snippet217204.html
Look for the TX and TY methds.
Have not much time now, will be back later if it did not help.

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;
        }

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!

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

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!

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.