Translate Rectangle Position in Zoom Mode Picturebox












2















I'm determining the rectangular area in an image and showing it to the user in a PictureBox.

Since the image can sometimes be very large, I'm using a PictureBox with its SizeMode set to Zoom.



I'm using the following code to translate the Rectangle (X, Y) coordinates:



public Point TranslateZoomMousePosition(Point coordinates)
{
// test to make sure our image is not null
if (pictureBox5.Image == null) return coordinates;
// Make sure our control width and height are not 0 and our
// image width and height are not 0
if (pictureBox5.Width == 0 || pictureBox5.Height == 0 || pictureBox5.Image.Width == 0 || pictureBox5.Image.Height == 0) return coordinates;
// This is the one that gets a little tricky. Essentially, need to check
// the aspect ratio of the image to the aspect ratio of the control
// to determine how it is being rendered
float imageAspect = (float)pictureBox5.Image.Width / pictureBox5.Image.Height;
float controlAspect = (float)pictureBox5.Width / pictureBox5.Height;
float newX = coordinates.X;
float newY = coordinates.Y;
if (imageAspect > controlAspect)
{
// This means that we are limited by width,
// meaning the image fills up the entire control from left to right
float ratioWidth = (float)pictureBox5.Image.Width / pictureBox5.Width;
newX *= ratioWidth;
float scale = (float)pictureBox5.Width / pictureBox5.Image.Width;
float displayHeight = scale * pictureBox5.Image.Height;
float diffHeight = pictureBox5.Height - displayHeight;
diffHeight /= 2;
newY -= diffHeight;
newY /= scale;
}
else
{
// This means that we are limited by height,
// meaning the image fills up the entire control from top to bottom
float ratioHeight = (float)pictureBox5.Image.Height / pictureBox5.Height;
newY *= ratioHeight;
float scale = (float)pictureBox5.Height / pictureBox5.Image.Height;
float displayWidth = scale * pictureBox5.Image.Width;
float diffWidth = pictureBox5.Width - displayWidth;
diffWidth /= 2;
newX -= diffWidth;
newX /= scale;
}
return new Point((int)newX, (int)newY);
}


Adding a frame control at the determined position:



pictureBox5.Controls.Clear();
var c = new FrameControl();
c.Size = new Size(myrect.Width, myrect.Height);
c.Location=TranslateZoomMousePosition(newPoint(myrect.Location.X,myrect.Location.Y));
pictureBox5.Controls.Add(c);


But the determined frame/rectangle location is not correct.

What am I i doing wrong?










share|improve this question





























    2















    I'm determining the rectangular area in an image and showing it to the user in a PictureBox.

    Since the image can sometimes be very large, I'm using a PictureBox with its SizeMode set to Zoom.



    I'm using the following code to translate the Rectangle (X, Y) coordinates:



    public Point TranslateZoomMousePosition(Point coordinates)
    {
    // test to make sure our image is not null
    if (pictureBox5.Image == null) return coordinates;
    // Make sure our control width and height are not 0 and our
    // image width and height are not 0
    if (pictureBox5.Width == 0 || pictureBox5.Height == 0 || pictureBox5.Image.Width == 0 || pictureBox5.Image.Height == 0) return coordinates;
    // This is the one that gets a little tricky. Essentially, need to check
    // the aspect ratio of the image to the aspect ratio of the control
    // to determine how it is being rendered
    float imageAspect = (float)pictureBox5.Image.Width / pictureBox5.Image.Height;
    float controlAspect = (float)pictureBox5.Width / pictureBox5.Height;
    float newX = coordinates.X;
    float newY = coordinates.Y;
    if (imageAspect > controlAspect)
    {
    // This means that we are limited by width,
    // meaning the image fills up the entire control from left to right
    float ratioWidth = (float)pictureBox5.Image.Width / pictureBox5.Width;
    newX *= ratioWidth;
    float scale = (float)pictureBox5.Width / pictureBox5.Image.Width;
    float displayHeight = scale * pictureBox5.Image.Height;
    float diffHeight = pictureBox5.Height - displayHeight;
    diffHeight /= 2;
    newY -= diffHeight;
    newY /= scale;
    }
    else
    {
    // This means that we are limited by height,
    // meaning the image fills up the entire control from top to bottom
    float ratioHeight = (float)pictureBox5.Image.Height / pictureBox5.Height;
    newY *= ratioHeight;
    float scale = (float)pictureBox5.Height / pictureBox5.Image.Height;
    float displayWidth = scale * pictureBox5.Image.Width;
    float diffWidth = pictureBox5.Width - displayWidth;
    diffWidth /= 2;
    newX -= diffWidth;
    newX /= scale;
    }
    return new Point((int)newX, (int)newY);
    }


    Adding a frame control at the determined position:



    pictureBox5.Controls.Clear();
    var c = new FrameControl();
    c.Size = new Size(myrect.Width, myrect.Height);
    c.Location=TranslateZoomMousePosition(newPoint(myrect.Location.X,myrect.Location.Y));
    pictureBox5.Controls.Add(c);


    But the determined frame/rectangle location is not correct.

    What am I i doing wrong?










    share|improve this question



























      2












      2








      2








      I'm determining the rectangular area in an image and showing it to the user in a PictureBox.

      Since the image can sometimes be very large, I'm using a PictureBox with its SizeMode set to Zoom.



      I'm using the following code to translate the Rectangle (X, Y) coordinates:



      public Point TranslateZoomMousePosition(Point coordinates)
      {
      // test to make sure our image is not null
      if (pictureBox5.Image == null) return coordinates;
      // Make sure our control width and height are not 0 and our
      // image width and height are not 0
      if (pictureBox5.Width == 0 || pictureBox5.Height == 0 || pictureBox5.Image.Width == 0 || pictureBox5.Image.Height == 0) return coordinates;
      // This is the one that gets a little tricky. Essentially, need to check
      // the aspect ratio of the image to the aspect ratio of the control
      // to determine how it is being rendered
      float imageAspect = (float)pictureBox5.Image.Width / pictureBox5.Image.Height;
      float controlAspect = (float)pictureBox5.Width / pictureBox5.Height;
      float newX = coordinates.X;
      float newY = coordinates.Y;
      if (imageAspect > controlAspect)
      {
      // This means that we are limited by width,
      // meaning the image fills up the entire control from left to right
      float ratioWidth = (float)pictureBox5.Image.Width / pictureBox5.Width;
      newX *= ratioWidth;
      float scale = (float)pictureBox5.Width / pictureBox5.Image.Width;
      float displayHeight = scale * pictureBox5.Image.Height;
      float diffHeight = pictureBox5.Height - displayHeight;
      diffHeight /= 2;
      newY -= diffHeight;
      newY /= scale;
      }
      else
      {
      // This means that we are limited by height,
      // meaning the image fills up the entire control from top to bottom
      float ratioHeight = (float)pictureBox5.Image.Height / pictureBox5.Height;
      newY *= ratioHeight;
      float scale = (float)pictureBox5.Height / pictureBox5.Image.Height;
      float displayWidth = scale * pictureBox5.Image.Width;
      float diffWidth = pictureBox5.Width - displayWidth;
      diffWidth /= 2;
      newX -= diffWidth;
      newX /= scale;
      }
      return new Point((int)newX, (int)newY);
      }


      Adding a frame control at the determined position:



      pictureBox5.Controls.Clear();
      var c = new FrameControl();
      c.Size = new Size(myrect.Width, myrect.Height);
      c.Location=TranslateZoomMousePosition(newPoint(myrect.Location.X,myrect.Location.Y));
      pictureBox5.Controls.Add(c);


      But the determined frame/rectangle location is not correct.

      What am I i doing wrong?










      share|improve this question
















      I'm determining the rectangular area in an image and showing it to the user in a PictureBox.

      Since the image can sometimes be very large, I'm using a PictureBox with its SizeMode set to Zoom.



      I'm using the following code to translate the Rectangle (X, Y) coordinates:



      public Point TranslateZoomMousePosition(Point coordinates)
      {
      // test to make sure our image is not null
      if (pictureBox5.Image == null) return coordinates;
      // Make sure our control width and height are not 0 and our
      // image width and height are not 0
      if (pictureBox5.Width == 0 || pictureBox5.Height == 0 || pictureBox5.Image.Width == 0 || pictureBox5.Image.Height == 0) return coordinates;
      // This is the one that gets a little tricky. Essentially, need to check
      // the aspect ratio of the image to the aspect ratio of the control
      // to determine how it is being rendered
      float imageAspect = (float)pictureBox5.Image.Width / pictureBox5.Image.Height;
      float controlAspect = (float)pictureBox5.Width / pictureBox5.Height;
      float newX = coordinates.X;
      float newY = coordinates.Y;
      if (imageAspect > controlAspect)
      {
      // This means that we are limited by width,
      // meaning the image fills up the entire control from left to right
      float ratioWidth = (float)pictureBox5.Image.Width / pictureBox5.Width;
      newX *= ratioWidth;
      float scale = (float)pictureBox5.Width / pictureBox5.Image.Width;
      float displayHeight = scale * pictureBox5.Image.Height;
      float diffHeight = pictureBox5.Height - displayHeight;
      diffHeight /= 2;
      newY -= diffHeight;
      newY /= scale;
      }
      else
      {
      // This means that we are limited by height,
      // meaning the image fills up the entire control from top to bottom
      float ratioHeight = (float)pictureBox5.Image.Height / pictureBox5.Height;
      newY *= ratioHeight;
      float scale = (float)pictureBox5.Height / pictureBox5.Image.Height;
      float displayWidth = scale * pictureBox5.Image.Width;
      float diffWidth = pictureBox5.Width - displayWidth;
      diffWidth /= 2;
      newX -= diffWidth;
      newX /= scale;
      }
      return new Point((int)newX, (int)newY);
      }


      Adding a frame control at the determined position:



      pictureBox5.Controls.Clear();
      var c = new FrameControl();
      c.Size = new Size(myrect.Width, myrect.Height);
      c.Location=TranslateZoomMousePosition(newPoint(myrect.Location.X,myrect.Location.Y));
      pictureBox5.Controls.Add(c);


      But the determined frame/rectangle location is not correct.

      What am I i doing wrong?







      c# .net winforms picturebox system.drawing






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 16 '18 at 16:41









      Jimi

      8,12241934




      8,12241934










      asked Dec 16 '18 at 7:38









      technotechno

      1,7431046101




      1,7431046101
























          2 Answers
          2






          active

          oldest

          votes


















          3














          You can translate selected rectangle on the picture box to the rectangle on image this way:



          public RectangleF GetRectangeOnImage(PictureBox p, Rectangle selectionRect)
          {
          var method = typeof(PictureBox).GetMethod("ImageRectangleFromSizeMode",
          System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
          var imageRect = (Rectangle)method.Invoke(p, new object { p.SizeMode });
          if (p.Image == null)
          return selectionRect;
          var cx = (float)p.Image.Width / (float)imageRect.Width;
          var cy = (float)p.Image.Height / (float)imageRect.Height;
          var r2 = Rectangle.Intersect(imageRect, selectionRect);
          r2.Offset(-imageRect.X, -imageRect.Y);
          return new RectangleF(r2.X * cx, r2.Y * cy, r2.Width * cx, r2.Height * cy);
          }


          Note: You can find ImageRectangleFromSizeMode method source code here and use it as write such method as part of your application code.



          Example - Crop Image of PictureBox having SizeMode = Zoom



          As an example, the following code will crop the given rectangle of the picture box 1 and will set the result as image of picture box 2:



          var selectedRectangle = new Rectangle(7, 30, 50, 40);
          var result = GetRectangeOnImage(pictureBox1, selectedRectangle);
          using (var bm = new Bitmap((int)result.Width, (int)result.Height))
          {
          using (var g = Graphics.FromImage(bm))
          g.DrawImage(pictureBox1.Image, 0, 0, result, GraphicsUnit.Pixel);
          pictureBox2.Image = (Image)bm.Clone();
          }


          Here is the input image:



          enter image description here



          And this is the result:



          enter image description here






          share|improve this answer





















          • 1





            ImageRectangleFromSizeMode wow, this is digging deep into the hidden vault!

            – TaW
            Dec 16 '18 at 9:53













          • @techno Changed a bit to support Stretch mode as well.

            – Reza Aghaei
            Dec 16 '18 at 10:04








          • 1





            @TaW Added the link to ImageRectangleFromSizeMode source code so future readers can use it and write such method as part of their application code.

            – Reza Aghaei
            Dec 16 '18 at 10:16








          • 1





            Ha! ImageRectangleFromSizeMode is something you usually see mentioned in stack traces (when something goes wrong). Well done!

            – Jimi
            Dec 16 '18 at 12:21











          • @RezaAghaei Actually also need to do the reverse ie: i have the rectangle coordinates on the original image.When this image is displayed in the picturebox,i need to place the movable frame at the correct position by translating its known position in the original image.

            – techno
            Dec 16 '18 at 17:33



















          2














          Consider this an addition to Reza Aghaei answer.





          A specialized class that provides some helper tools to determine the scaling factor of a selection and translates the selection coordinates to the scaled Bitmap coordinates.

          This version is for zoomed images only.



          The ZoomFactor class provides these methods:



          PointF TranslateZoomPosition(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize):

          returns the PointF translated coordinates of a Point location inside a Container to the Point location inside a Bitmap, zoomed in the container.



          RectangleF TranslateZoomSelection(RectangleF Selection, SizeF ContainerSize, SizeF ImageSize):

          returns a RectangleF representing a selection created inside a Container, translated to the Bitmap coordinates.



          RectangleF TranslateSelectionToZoomedSel(RectangleF SelectionRect, SizeF ContainerSize, SizeF ImageSize):

          returns a RectangleF representing a pre-selected area of the original Bitmap translated to the zoomed selection Image inside a Container.



          PointF GetImageScaledOrigin(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize):

          returns the PointF reference of the zoomed Image origin coordinates inside the Container.



          SizeF GetImageScaledSize(SizeF ContainerSize, SizeF ImageSize):

          returns the SizeF reference of the Image when scaled inside the Container.



          Sample usage, showing how to crop a Bitmap using a selection Rectangle created inside a Container control. The TranslateZoomSelection method returns the Bitmap section corresponding to a selection area:



          ZoomFactor ZoomHelper = new ZoomFactor()
          Bitmap originalBitmap;

          RectangleF currentSelection = [Current Selection Rectangle];
          RectangleF bitmapRect = ZoomHelper.TranslateZoomSelection(currentSelection, [Container].Size, originalBitmap.Size);
          using (Bitmap croppedBitmap = new Bitmap((int)bitmapRect.Width, (int)bitmapRect.Height, originalBitmap.PixelFormat))
          using (Graphics g = Graphics.FromImage(croppedBitmap))
          {
          g.DrawImage(originalBitmap, new Rectangle(Point.Empty, Size.Round(bitmapRect.Size)),
          bitmapRect, GraphicsUnit.Pixel);
          [Container].Image = (Bitmap)croppedBitmap.Clone();
          }


          A Sample of the behaviour described above:



          PictureBox Zoom Selection



          Note: In the example, the pre-selection of the image in Portrait inverts Width and Height



          The ZoomFactor class:



          public class ZoomFactor
          {
          public ZoomFactor() { }

          public PointF TranslateZoomPosition(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize)
          {
          PointF imageOrigin = TranslateCoordinatesOrigin(Coordinates, ContainerSize, ImageSize);
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);
          return new PointF(imageOrigin.X / scaleFactor, imageOrigin.Y / scaleFactor);
          }

          public RectangleF TranslateZoomSelection(RectangleF SelectionRect, SizeF ContainerSize, SizeF ImageSize)
          {
          PointF selectionTrueOrigin = TranslateZoomPosition(SelectionRect.Location, ContainerSize, ImageSize);
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);

          SizeF selectionTrueSize = new SizeF(SelectionRect.Width / scaleFactor, SelectionRect.Height / scaleFactor);
          return new RectangleF(selectionTrueOrigin, selectionTrueSize);
          }

          public RectangleF TranslateSelectionToZoomedSel(RectangleF SelectionRect, SizeF ContainerSize, SizeF ImageSize)
          {
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);
          RectangleF zoomedSelectionRect = new
          RectangleF(SelectionRect.X * scaleFactor, SelectionRect.Y * scaleFactor,
          SelectionRect.Width * scaleFactor, SelectionRect.Height * scaleFactor);

          PointF imageScaledOrigin = GetImageScaledOrigin(ContainerSize, ImageSize);
          zoomedSelectionRect.Location = new PointF(zoomedSelectionRect.Location.X + imageScaledOrigin.X,
          zoomedSelectionRect.Location.Y + imageScaledOrigin.Y);
          return zoomedSelectionRect;
          }

          public PointF TranslateCoordinatesOrigin(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize)
          {
          PointF imageOrigin = GetImageScaledOrigin(ContainerSize, ImageSize);
          return new PointF(Coordinates.X - imageOrigin.X, Coordinates.Y - imageOrigin.Y);
          }

          public PointF GetImageScaledOrigin(SizeF ContainerSize, SizeF ImageSize)
          {
          SizeF imageScaleSize = GetImageScaledSize(ContainerSize, ImageSize);
          return new PointF((ContainerSize.Width - imageScaleSize.Width) / 2,
          (ContainerSize.Height - imageScaleSize.Height) / 2);
          }

          public SizeF GetImageScaledSize(SizeF ContainerSize, SizeF ImageSize)
          {
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);
          return new SizeF(ImageSize.Width * scaleFactor, ImageSize.Height * scaleFactor);

          }
          internal float GetScaleFactor(SizeF Scaled, SizeF Original)
          {
          return (Original.Width > Original.Height) ? (Scaled.Width / Original.Width)
          : (Scaled.Height / Original.Height);
          }
          }





          share|improve this answer


























          • Thanks a lot :). I will take a look at both of your answers.

            – techno
            Dec 16 '18 at 12:58











          • Actually also need to do the reverse ie: i have the rectangle coordinates on the original image.When this image is displayed in the picturebox,i need to place the movable frame at the correct position by translating its known position in the original image.

            – techno
            Dec 16 '18 at 17:34











          • @techno See the edit. I've added a selection translator from coordinates relative to the original image to the scaled image (and a sample animation too :). I didn't have not much time, so it's not tested properly, but I've made some slections in different conditions and it looks OK. I'll revise it tomorrow.

            – Jimi
            Dec 16 '18 at 20:37











          • okay...Thanks... :)

            – techno
            Dec 18 '18 at 2:27











          • How do i detect if the control was resized or moved in the picturebox? Currently i use picturebox mouse mouse event. Is there a better way?

            – techno
            Dec 18 '18 at 2:27











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53800328%2ftranslate-rectangle-position-in-zoom-mode-picturebox%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          3














          You can translate selected rectangle on the picture box to the rectangle on image this way:



          public RectangleF GetRectangeOnImage(PictureBox p, Rectangle selectionRect)
          {
          var method = typeof(PictureBox).GetMethod("ImageRectangleFromSizeMode",
          System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
          var imageRect = (Rectangle)method.Invoke(p, new object { p.SizeMode });
          if (p.Image == null)
          return selectionRect;
          var cx = (float)p.Image.Width / (float)imageRect.Width;
          var cy = (float)p.Image.Height / (float)imageRect.Height;
          var r2 = Rectangle.Intersect(imageRect, selectionRect);
          r2.Offset(-imageRect.X, -imageRect.Y);
          return new RectangleF(r2.X * cx, r2.Y * cy, r2.Width * cx, r2.Height * cy);
          }


          Note: You can find ImageRectangleFromSizeMode method source code here and use it as write such method as part of your application code.



          Example - Crop Image of PictureBox having SizeMode = Zoom



          As an example, the following code will crop the given rectangle of the picture box 1 and will set the result as image of picture box 2:



          var selectedRectangle = new Rectangle(7, 30, 50, 40);
          var result = GetRectangeOnImage(pictureBox1, selectedRectangle);
          using (var bm = new Bitmap((int)result.Width, (int)result.Height))
          {
          using (var g = Graphics.FromImage(bm))
          g.DrawImage(pictureBox1.Image, 0, 0, result, GraphicsUnit.Pixel);
          pictureBox2.Image = (Image)bm.Clone();
          }


          Here is the input image:



          enter image description here



          And this is the result:



          enter image description here






          share|improve this answer





















          • 1





            ImageRectangleFromSizeMode wow, this is digging deep into the hidden vault!

            – TaW
            Dec 16 '18 at 9:53













          • @techno Changed a bit to support Stretch mode as well.

            – Reza Aghaei
            Dec 16 '18 at 10:04








          • 1





            @TaW Added the link to ImageRectangleFromSizeMode source code so future readers can use it and write such method as part of their application code.

            – Reza Aghaei
            Dec 16 '18 at 10:16








          • 1





            Ha! ImageRectangleFromSizeMode is something you usually see mentioned in stack traces (when something goes wrong). Well done!

            – Jimi
            Dec 16 '18 at 12:21











          • @RezaAghaei Actually also need to do the reverse ie: i have the rectangle coordinates on the original image.When this image is displayed in the picturebox,i need to place the movable frame at the correct position by translating its known position in the original image.

            – techno
            Dec 16 '18 at 17:33
















          3














          You can translate selected rectangle on the picture box to the rectangle on image this way:



          public RectangleF GetRectangeOnImage(PictureBox p, Rectangle selectionRect)
          {
          var method = typeof(PictureBox).GetMethod("ImageRectangleFromSizeMode",
          System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
          var imageRect = (Rectangle)method.Invoke(p, new object { p.SizeMode });
          if (p.Image == null)
          return selectionRect;
          var cx = (float)p.Image.Width / (float)imageRect.Width;
          var cy = (float)p.Image.Height / (float)imageRect.Height;
          var r2 = Rectangle.Intersect(imageRect, selectionRect);
          r2.Offset(-imageRect.X, -imageRect.Y);
          return new RectangleF(r2.X * cx, r2.Y * cy, r2.Width * cx, r2.Height * cy);
          }


          Note: You can find ImageRectangleFromSizeMode method source code here and use it as write such method as part of your application code.



          Example - Crop Image of PictureBox having SizeMode = Zoom



          As an example, the following code will crop the given rectangle of the picture box 1 and will set the result as image of picture box 2:



          var selectedRectangle = new Rectangle(7, 30, 50, 40);
          var result = GetRectangeOnImage(pictureBox1, selectedRectangle);
          using (var bm = new Bitmap((int)result.Width, (int)result.Height))
          {
          using (var g = Graphics.FromImage(bm))
          g.DrawImage(pictureBox1.Image, 0, 0, result, GraphicsUnit.Pixel);
          pictureBox2.Image = (Image)bm.Clone();
          }


          Here is the input image:



          enter image description here



          And this is the result:



          enter image description here






          share|improve this answer





















          • 1





            ImageRectangleFromSizeMode wow, this is digging deep into the hidden vault!

            – TaW
            Dec 16 '18 at 9:53













          • @techno Changed a bit to support Stretch mode as well.

            – Reza Aghaei
            Dec 16 '18 at 10:04








          • 1





            @TaW Added the link to ImageRectangleFromSizeMode source code so future readers can use it and write such method as part of their application code.

            – Reza Aghaei
            Dec 16 '18 at 10:16








          • 1





            Ha! ImageRectangleFromSizeMode is something you usually see mentioned in stack traces (when something goes wrong). Well done!

            – Jimi
            Dec 16 '18 at 12:21











          • @RezaAghaei Actually also need to do the reverse ie: i have the rectangle coordinates on the original image.When this image is displayed in the picturebox,i need to place the movable frame at the correct position by translating its known position in the original image.

            – techno
            Dec 16 '18 at 17:33














          3












          3








          3







          You can translate selected rectangle on the picture box to the rectangle on image this way:



          public RectangleF GetRectangeOnImage(PictureBox p, Rectangle selectionRect)
          {
          var method = typeof(PictureBox).GetMethod("ImageRectangleFromSizeMode",
          System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
          var imageRect = (Rectangle)method.Invoke(p, new object { p.SizeMode });
          if (p.Image == null)
          return selectionRect;
          var cx = (float)p.Image.Width / (float)imageRect.Width;
          var cy = (float)p.Image.Height / (float)imageRect.Height;
          var r2 = Rectangle.Intersect(imageRect, selectionRect);
          r2.Offset(-imageRect.X, -imageRect.Y);
          return new RectangleF(r2.X * cx, r2.Y * cy, r2.Width * cx, r2.Height * cy);
          }


          Note: You can find ImageRectangleFromSizeMode method source code here and use it as write such method as part of your application code.



          Example - Crop Image of PictureBox having SizeMode = Zoom



          As an example, the following code will crop the given rectangle of the picture box 1 and will set the result as image of picture box 2:



          var selectedRectangle = new Rectangle(7, 30, 50, 40);
          var result = GetRectangeOnImage(pictureBox1, selectedRectangle);
          using (var bm = new Bitmap((int)result.Width, (int)result.Height))
          {
          using (var g = Graphics.FromImage(bm))
          g.DrawImage(pictureBox1.Image, 0, 0, result, GraphicsUnit.Pixel);
          pictureBox2.Image = (Image)bm.Clone();
          }


          Here is the input image:



          enter image description here



          And this is the result:



          enter image description here






          share|improve this answer















          You can translate selected rectangle on the picture box to the rectangle on image this way:



          public RectangleF GetRectangeOnImage(PictureBox p, Rectangle selectionRect)
          {
          var method = typeof(PictureBox).GetMethod("ImageRectangleFromSizeMode",
          System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
          var imageRect = (Rectangle)method.Invoke(p, new object { p.SizeMode });
          if (p.Image == null)
          return selectionRect;
          var cx = (float)p.Image.Width / (float)imageRect.Width;
          var cy = (float)p.Image.Height / (float)imageRect.Height;
          var r2 = Rectangle.Intersect(imageRect, selectionRect);
          r2.Offset(-imageRect.X, -imageRect.Y);
          return new RectangleF(r2.X * cx, r2.Y * cy, r2.Width * cx, r2.Height * cy);
          }


          Note: You can find ImageRectangleFromSizeMode method source code here and use it as write such method as part of your application code.



          Example - Crop Image of PictureBox having SizeMode = Zoom



          As an example, the following code will crop the given rectangle of the picture box 1 and will set the result as image of picture box 2:



          var selectedRectangle = new Rectangle(7, 30, 50, 40);
          var result = GetRectangeOnImage(pictureBox1, selectedRectangle);
          using (var bm = new Bitmap((int)result.Width, (int)result.Height))
          {
          using (var g = Graphics.FromImage(bm))
          g.DrawImage(pictureBox1.Image, 0, 0, result, GraphicsUnit.Pixel);
          pictureBox2.Image = (Image)bm.Clone();
          }


          Here is the input image:



          enter image description here



          And this is the result:



          enter image description here







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Dec 16 '18 at 10:12

























          answered Dec 16 '18 at 8:24









          Reza AghaeiReza Aghaei

          65.9k854162




          65.9k854162








          • 1





            ImageRectangleFromSizeMode wow, this is digging deep into the hidden vault!

            – TaW
            Dec 16 '18 at 9:53













          • @techno Changed a bit to support Stretch mode as well.

            – Reza Aghaei
            Dec 16 '18 at 10:04








          • 1





            @TaW Added the link to ImageRectangleFromSizeMode source code so future readers can use it and write such method as part of their application code.

            – Reza Aghaei
            Dec 16 '18 at 10:16








          • 1





            Ha! ImageRectangleFromSizeMode is something you usually see mentioned in stack traces (when something goes wrong). Well done!

            – Jimi
            Dec 16 '18 at 12:21











          • @RezaAghaei Actually also need to do the reverse ie: i have the rectangle coordinates on the original image.When this image is displayed in the picturebox,i need to place the movable frame at the correct position by translating its known position in the original image.

            – techno
            Dec 16 '18 at 17:33














          • 1





            ImageRectangleFromSizeMode wow, this is digging deep into the hidden vault!

            – TaW
            Dec 16 '18 at 9:53













          • @techno Changed a bit to support Stretch mode as well.

            – Reza Aghaei
            Dec 16 '18 at 10:04








          • 1





            @TaW Added the link to ImageRectangleFromSizeMode source code so future readers can use it and write such method as part of their application code.

            – Reza Aghaei
            Dec 16 '18 at 10:16








          • 1





            Ha! ImageRectangleFromSizeMode is something you usually see mentioned in stack traces (when something goes wrong). Well done!

            – Jimi
            Dec 16 '18 at 12:21











          • @RezaAghaei Actually also need to do the reverse ie: i have the rectangle coordinates on the original image.When this image is displayed in the picturebox,i need to place the movable frame at the correct position by translating its known position in the original image.

            – techno
            Dec 16 '18 at 17:33








          1




          1





          ImageRectangleFromSizeMode wow, this is digging deep into the hidden vault!

          – TaW
          Dec 16 '18 at 9:53







          ImageRectangleFromSizeMode wow, this is digging deep into the hidden vault!

          – TaW
          Dec 16 '18 at 9:53















          @techno Changed a bit to support Stretch mode as well.

          – Reza Aghaei
          Dec 16 '18 at 10:04







          @techno Changed a bit to support Stretch mode as well.

          – Reza Aghaei
          Dec 16 '18 at 10:04






          1




          1





          @TaW Added the link to ImageRectangleFromSizeMode source code so future readers can use it and write such method as part of their application code.

          – Reza Aghaei
          Dec 16 '18 at 10:16







          @TaW Added the link to ImageRectangleFromSizeMode source code so future readers can use it and write such method as part of their application code.

          – Reza Aghaei
          Dec 16 '18 at 10:16






          1




          1





          Ha! ImageRectangleFromSizeMode is something you usually see mentioned in stack traces (when something goes wrong). Well done!

          – Jimi
          Dec 16 '18 at 12:21





          Ha! ImageRectangleFromSizeMode is something you usually see mentioned in stack traces (when something goes wrong). Well done!

          – Jimi
          Dec 16 '18 at 12:21













          @RezaAghaei Actually also need to do the reverse ie: i have the rectangle coordinates on the original image.When this image is displayed in the picturebox,i need to place the movable frame at the correct position by translating its known position in the original image.

          – techno
          Dec 16 '18 at 17:33





          @RezaAghaei Actually also need to do the reverse ie: i have the rectangle coordinates on the original image.When this image is displayed in the picturebox,i need to place the movable frame at the correct position by translating its known position in the original image.

          – techno
          Dec 16 '18 at 17:33













          2














          Consider this an addition to Reza Aghaei answer.





          A specialized class that provides some helper tools to determine the scaling factor of a selection and translates the selection coordinates to the scaled Bitmap coordinates.

          This version is for zoomed images only.



          The ZoomFactor class provides these methods:



          PointF TranslateZoomPosition(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize):

          returns the PointF translated coordinates of a Point location inside a Container to the Point location inside a Bitmap, zoomed in the container.



          RectangleF TranslateZoomSelection(RectangleF Selection, SizeF ContainerSize, SizeF ImageSize):

          returns a RectangleF representing a selection created inside a Container, translated to the Bitmap coordinates.



          RectangleF TranslateSelectionToZoomedSel(RectangleF SelectionRect, SizeF ContainerSize, SizeF ImageSize):

          returns a RectangleF representing a pre-selected area of the original Bitmap translated to the zoomed selection Image inside a Container.



          PointF GetImageScaledOrigin(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize):

          returns the PointF reference of the zoomed Image origin coordinates inside the Container.



          SizeF GetImageScaledSize(SizeF ContainerSize, SizeF ImageSize):

          returns the SizeF reference of the Image when scaled inside the Container.



          Sample usage, showing how to crop a Bitmap using a selection Rectangle created inside a Container control. The TranslateZoomSelection method returns the Bitmap section corresponding to a selection area:



          ZoomFactor ZoomHelper = new ZoomFactor()
          Bitmap originalBitmap;

          RectangleF currentSelection = [Current Selection Rectangle];
          RectangleF bitmapRect = ZoomHelper.TranslateZoomSelection(currentSelection, [Container].Size, originalBitmap.Size);
          using (Bitmap croppedBitmap = new Bitmap((int)bitmapRect.Width, (int)bitmapRect.Height, originalBitmap.PixelFormat))
          using (Graphics g = Graphics.FromImage(croppedBitmap))
          {
          g.DrawImage(originalBitmap, new Rectangle(Point.Empty, Size.Round(bitmapRect.Size)),
          bitmapRect, GraphicsUnit.Pixel);
          [Container].Image = (Bitmap)croppedBitmap.Clone();
          }


          A Sample of the behaviour described above:



          PictureBox Zoom Selection



          Note: In the example, the pre-selection of the image in Portrait inverts Width and Height



          The ZoomFactor class:



          public class ZoomFactor
          {
          public ZoomFactor() { }

          public PointF TranslateZoomPosition(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize)
          {
          PointF imageOrigin = TranslateCoordinatesOrigin(Coordinates, ContainerSize, ImageSize);
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);
          return new PointF(imageOrigin.X / scaleFactor, imageOrigin.Y / scaleFactor);
          }

          public RectangleF TranslateZoomSelection(RectangleF SelectionRect, SizeF ContainerSize, SizeF ImageSize)
          {
          PointF selectionTrueOrigin = TranslateZoomPosition(SelectionRect.Location, ContainerSize, ImageSize);
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);

          SizeF selectionTrueSize = new SizeF(SelectionRect.Width / scaleFactor, SelectionRect.Height / scaleFactor);
          return new RectangleF(selectionTrueOrigin, selectionTrueSize);
          }

          public RectangleF TranslateSelectionToZoomedSel(RectangleF SelectionRect, SizeF ContainerSize, SizeF ImageSize)
          {
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);
          RectangleF zoomedSelectionRect = new
          RectangleF(SelectionRect.X * scaleFactor, SelectionRect.Y * scaleFactor,
          SelectionRect.Width * scaleFactor, SelectionRect.Height * scaleFactor);

          PointF imageScaledOrigin = GetImageScaledOrigin(ContainerSize, ImageSize);
          zoomedSelectionRect.Location = new PointF(zoomedSelectionRect.Location.X + imageScaledOrigin.X,
          zoomedSelectionRect.Location.Y + imageScaledOrigin.Y);
          return zoomedSelectionRect;
          }

          public PointF TranslateCoordinatesOrigin(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize)
          {
          PointF imageOrigin = GetImageScaledOrigin(ContainerSize, ImageSize);
          return new PointF(Coordinates.X - imageOrigin.X, Coordinates.Y - imageOrigin.Y);
          }

          public PointF GetImageScaledOrigin(SizeF ContainerSize, SizeF ImageSize)
          {
          SizeF imageScaleSize = GetImageScaledSize(ContainerSize, ImageSize);
          return new PointF((ContainerSize.Width - imageScaleSize.Width) / 2,
          (ContainerSize.Height - imageScaleSize.Height) / 2);
          }

          public SizeF GetImageScaledSize(SizeF ContainerSize, SizeF ImageSize)
          {
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);
          return new SizeF(ImageSize.Width * scaleFactor, ImageSize.Height * scaleFactor);

          }
          internal float GetScaleFactor(SizeF Scaled, SizeF Original)
          {
          return (Original.Width > Original.Height) ? (Scaled.Width / Original.Width)
          : (Scaled.Height / Original.Height);
          }
          }





          share|improve this answer


























          • Thanks a lot :). I will take a look at both of your answers.

            – techno
            Dec 16 '18 at 12:58











          • Actually also need to do the reverse ie: i have the rectangle coordinates on the original image.When this image is displayed in the picturebox,i need to place the movable frame at the correct position by translating its known position in the original image.

            – techno
            Dec 16 '18 at 17:34











          • @techno See the edit. I've added a selection translator from coordinates relative to the original image to the scaled image (and a sample animation too :). I didn't have not much time, so it's not tested properly, but I've made some slections in different conditions and it looks OK. I'll revise it tomorrow.

            – Jimi
            Dec 16 '18 at 20:37











          • okay...Thanks... :)

            – techno
            Dec 18 '18 at 2:27











          • How do i detect if the control was resized or moved in the picturebox? Currently i use picturebox mouse mouse event. Is there a better way?

            – techno
            Dec 18 '18 at 2:27
















          2














          Consider this an addition to Reza Aghaei answer.





          A specialized class that provides some helper tools to determine the scaling factor of a selection and translates the selection coordinates to the scaled Bitmap coordinates.

          This version is for zoomed images only.



          The ZoomFactor class provides these methods:



          PointF TranslateZoomPosition(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize):

          returns the PointF translated coordinates of a Point location inside a Container to the Point location inside a Bitmap, zoomed in the container.



          RectangleF TranslateZoomSelection(RectangleF Selection, SizeF ContainerSize, SizeF ImageSize):

          returns a RectangleF representing a selection created inside a Container, translated to the Bitmap coordinates.



          RectangleF TranslateSelectionToZoomedSel(RectangleF SelectionRect, SizeF ContainerSize, SizeF ImageSize):

          returns a RectangleF representing a pre-selected area of the original Bitmap translated to the zoomed selection Image inside a Container.



          PointF GetImageScaledOrigin(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize):

          returns the PointF reference of the zoomed Image origin coordinates inside the Container.



          SizeF GetImageScaledSize(SizeF ContainerSize, SizeF ImageSize):

          returns the SizeF reference of the Image when scaled inside the Container.



          Sample usage, showing how to crop a Bitmap using a selection Rectangle created inside a Container control. The TranslateZoomSelection method returns the Bitmap section corresponding to a selection area:



          ZoomFactor ZoomHelper = new ZoomFactor()
          Bitmap originalBitmap;

          RectangleF currentSelection = [Current Selection Rectangle];
          RectangleF bitmapRect = ZoomHelper.TranslateZoomSelection(currentSelection, [Container].Size, originalBitmap.Size);
          using (Bitmap croppedBitmap = new Bitmap((int)bitmapRect.Width, (int)bitmapRect.Height, originalBitmap.PixelFormat))
          using (Graphics g = Graphics.FromImage(croppedBitmap))
          {
          g.DrawImage(originalBitmap, new Rectangle(Point.Empty, Size.Round(bitmapRect.Size)),
          bitmapRect, GraphicsUnit.Pixel);
          [Container].Image = (Bitmap)croppedBitmap.Clone();
          }


          A Sample of the behaviour described above:



          PictureBox Zoom Selection



          Note: In the example, the pre-selection of the image in Portrait inverts Width and Height



          The ZoomFactor class:



          public class ZoomFactor
          {
          public ZoomFactor() { }

          public PointF TranslateZoomPosition(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize)
          {
          PointF imageOrigin = TranslateCoordinatesOrigin(Coordinates, ContainerSize, ImageSize);
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);
          return new PointF(imageOrigin.X / scaleFactor, imageOrigin.Y / scaleFactor);
          }

          public RectangleF TranslateZoomSelection(RectangleF SelectionRect, SizeF ContainerSize, SizeF ImageSize)
          {
          PointF selectionTrueOrigin = TranslateZoomPosition(SelectionRect.Location, ContainerSize, ImageSize);
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);

          SizeF selectionTrueSize = new SizeF(SelectionRect.Width / scaleFactor, SelectionRect.Height / scaleFactor);
          return new RectangleF(selectionTrueOrigin, selectionTrueSize);
          }

          public RectangleF TranslateSelectionToZoomedSel(RectangleF SelectionRect, SizeF ContainerSize, SizeF ImageSize)
          {
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);
          RectangleF zoomedSelectionRect = new
          RectangleF(SelectionRect.X * scaleFactor, SelectionRect.Y * scaleFactor,
          SelectionRect.Width * scaleFactor, SelectionRect.Height * scaleFactor);

          PointF imageScaledOrigin = GetImageScaledOrigin(ContainerSize, ImageSize);
          zoomedSelectionRect.Location = new PointF(zoomedSelectionRect.Location.X + imageScaledOrigin.X,
          zoomedSelectionRect.Location.Y + imageScaledOrigin.Y);
          return zoomedSelectionRect;
          }

          public PointF TranslateCoordinatesOrigin(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize)
          {
          PointF imageOrigin = GetImageScaledOrigin(ContainerSize, ImageSize);
          return new PointF(Coordinates.X - imageOrigin.X, Coordinates.Y - imageOrigin.Y);
          }

          public PointF GetImageScaledOrigin(SizeF ContainerSize, SizeF ImageSize)
          {
          SizeF imageScaleSize = GetImageScaledSize(ContainerSize, ImageSize);
          return new PointF((ContainerSize.Width - imageScaleSize.Width) / 2,
          (ContainerSize.Height - imageScaleSize.Height) / 2);
          }

          public SizeF GetImageScaledSize(SizeF ContainerSize, SizeF ImageSize)
          {
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);
          return new SizeF(ImageSize.Width * scaleFactor, ImageSize.Height * scaleFactor);

          }
          internal float GetScaleFactor(SizeF Scaled, SizeF Original)
          {
          return (Original.Width > Original.Height) ? (Scaled.Width / Original.Width)
          : (Scaled.Height / Original.Height);
          }
          }





          share|improve this answer


























          • Thanks a lot :). I will take a look at both of your answers.

            – techno
            Dec 16 '18 at 12:58











          • Actually also need to do the reverse ie: i have the rectangle coordinates on the original image.When this image is displayed in the picturebox,i need to place the movable frame at the correct position by translating its known position in the original image.

            – techno
            Dec 16 '18 at 17:34











          • @techno See the edit. I've added a selection translator from coordinates relative to the original image to the scaled image (and a sample animation too :). I didn't have not much time, so it's not tested properly, but I've made some slections in different conditions and it looks OK. I'll revise it tomorrow.

            – Jimi
            Dec 16 '18 at 20:37











          • okay...Thanks... :)

            – techno
            Dec 18 '18 at 2:27











          • How do i detect if the control was resized or moved in the picturebox? Currently i use picturebox mouse mouse event. Is there a better way?

            – techno
            Dec 18 '18 at 2:27














          2












          2








          2







          Consider this an addition to Reza Aghaei answer.





          A specialized class that provides some helper tools to determine the scaling factor of a selection and translates the selection coordinates to the scaled Bitmap coordinates.

          This version is for zoomed images only.



          The ZoomFactor class provides these methods:



          PointF TranslateZoomPosition(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize):

          returns the PointF translated coordinates of a Point location inside a Container to the Point location inside a Bitmap, zoomed in the container.



          RectangleF TranslateZoomSelection(RectangleF Selection, SizeF ContainerSize, SizeF ImageSize):

          returns a RectangleF representing a selection created inside a Container, translated to the Bitmap coordinates.



          RectangleF TranslateSelectionToZoomedSel(RectangleF SelectionRect, SizeF ContainerSize, SizeF ImageSize):

          returns a RectangleF representing a pre-selected area of the original Bitmap translated to the zoomed selection Image inside a Container.



          PointF GetImageScaledOrigin(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize):

          returns the PointF reference of the zoomed Image origin coordinates inside the Container.



          SizeF GetImageScaledSize(SizeF ContainerSize, SizeF ImageSize):

          returns the SizeF reference of the Image when scaled inside the Container.



          Sample usage, showing how to crop a Bitmap using a selection Rectangle created inside a Container control. The TranslateZoomSelection method returns the Bitmap section corresponding to a selection area:



          ZoomFactor ZoomHelper = new ZoomFactor()
          Bitmap originalBitmap;

          RectangleF currentSelection = [Current Selection Rectangle];
          RectangleF bitmapRect = ZoomHelper.TranslateZoomSelection(currentSelection, [Container].Size, originalBitmap.Size);
          using (Bitmap croppedBitmap = new Bitmap((int)bitmapRect.Width, (int)bitmapRect.Height, originalBitmap.PixelFormat))
          using (Graphics g = Graphics.FromImage(croppedBitmap))
          {
          g.DrawImage(originalBitmap, new Rectangle(Point.Empty, Size.Round(bitmapRect.Size)),
          bitmapRect, GraphicsUnit.Pixel);
          [Container].Image = (Bitmap)croppedBitmap.Clone();
          }


          A Sample of the behaviour described above:



          PictureBox Zoom Selection



          Note: In the example, the pre-selection of the image in Portrait inverts Width and Height



          The ZoomFactor class:



          public class ZoomFactor
          {
          public ZoomFactor() { }

          public PointF TranslateZoomPosition(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize)
          {
          PointF imageOrigin = TranslateCoordinatesOrigin(Coordinates, ContainerSize, ImageSize);
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);
          return new PointF(imageOrigin.X / scaleFactor, imageOrigin.Y / scaleFactor);
          }

          public RectangleF TranslateZoomSelection(RectangleF SelectionRect, SizeF ContainerSize, SizeF ImageSize)
          {
          PointF selectionTrueOrigin = TranslateZoomPosition(SelectionRect.Location, ContainerSize, ImageSize);
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);

          SizeF selectionTrueSize = new SizeF(SelectionRect.Width / scaleFactor, SelectionRect.Height / scaleFactor);
          return new RectangleF(selectionTrueOrigin, selectionTrueSize);
          }

          public RectangleF TranslateSelectionToZoomedSel(RectangleF SelectionRect, SizeF ContainerSize, SizeF ImageSize)
          {
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);
          RectangleF zoomedSelectionRect = new
          RectangleF(SelectionRect.X * scaleFactor, SelectionRect.Y * scaleFactor,
          SelectionRect.Width * scaleFactor, SelectionRect.Height * scaleFactor);

          PointF imageScaledOrigin = GetImageScaledOrigin(ContainerSize, ImageSize);
          zoomedSelectionRect.Location = new PointF(zoomedSelectionRect.Location.X + imageScaledOrigin.X,
          zoomedSelectionRect.Location.Y + imageScaledOrigin.Y);
          return zoomedSelectionRect;
          }

          public PointF TranslateCoordinatesOrigin(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize)
          {
          PointF imageOrigin = GetImageScaledOrigin(ContainerSize, ImageSize);
          return new PointF(Coordinates.X - imageOrigin.X, Coordinates.Y - imageOrigin.Y);
          }

          public PointF GetImageScaledOrigin(SizeF ContainerSize, SizeF ImageSize)
          {
          SizeF imageScaleSize = GetImageScaledSize(ContainerSize, ImageSize);
          return new PointF((ContainerSize.Width - imageScaleSize.Width) / 2,
          (ContainerSize.Height - imageScaleSize.Height) / 2);
          }

          public SizeF GetImageScaledSize(SizeF ContainerSize, SizeF ImageSize)
          {
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);
          return new SizeF(ImageSize.Width * scaleFactor, ImageSize.Height * scaleFactor);

          }
          internal float GetScaleFactor(SizeF Scaled, SizeF Original)
          {
          return (Original.Width > Original.Height) ? (Scaled.Width / Original.Width)
          : (Scaled.Height / Original.Height);
          }
          }





          share|improve this answer















          Consider this an addition to Reza Aghaei answer.





          A specialized class that provides some helper tools to determine the scaling factor of a selection and translates the selection coordinates to the scaled Bitmap coordinates.

          This version is for zoomed images only.



          The ZoomFactor class provides these methods:



          PointF TranslateZoomPosition(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize):

          returns the PointF translated coordinates of a Point location inside a Container to the Point location inside a Bitmap, zoomed in the container.



          RectangleF TranslateZoomSelection(RectangleF Selection, SizeF ContainerSize, SizeF ImageSize):

          returns a RectangleF representing a selection created inside a Container, translated to the Bitmap coordinates.



          RectangleF TranslateSelectionToZoomedSel(RectangleF SelectionRect, SizeF ContainerSize, SizeF ImageSize):

          returns a RectangleF representing a pre-selected area of the original Bitmap translated to the zoomed selection Image inside a Container.



          PointF GetImageScaledOrigin(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize):

          returns the PointF reference of the zoomed Image origin coordinates inside the Container.



          SizeF GetImageScaledSize(SizeF ContainerSize, SizeF ImageSize):

          returns the SizeF reference of the Image when scaled inside the Container.



          Sample usage, showing how to crop a Bitmap using a selection Rectangle created inside a Container control. The TranslateZoomSelection method returns the Bitmap section corresponding to a selection area:



          ZoomFactor ZoomHelper = new ZoomFactor()
          Bitmap originalBitmap;

          RectangleF currentSelection = [Current Selection Rectangle];
          RectangleF bitmapRect = ZoomHelper.TranslateZoomSelection(currentSelection, [Container].Size, originalBitmap.Size);
          using (Bitmap croppedBitmap = new Bitmap((int)bitmapRect.Width, (int)bitmapRect.Height, originalBitmap.PixelFormat))
          using (Graphics g = Graphics.FromImage(croppedBitmap))
          {
          g.DrawImage(originalBitmap, new Rectangle(Point.Empty, Size.Round(bitmapRect.Size)),
          bitmapRect, GraphicsUnit.Pixel);
          [Container].Image = (Bitmap)croppedBitmap.Clone();
          }


          A Sample of the behaviour described above:



          PictureBox Zoom Selection



          Note: In the example, the pre-selection of the image in Portrait inverts Width and Height



          The ZoomFactor class:



          public class ZoomFactor
          {
          public ZoomFactor() { }

          public PointF TranslateZoomPosition(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize)
          {
          PointF imageOrigin = TranslateCoordinatesOrigin(Coordinates, ContainerSize, ImageSize);
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);
          return new PointF(imageOrigin.X / scaleFactor, imageOrigin.Y / scaleFactor);
          }

          public RectangleF TranslateZoomSelection(RectangleF SelectionRect, SizeF ContainerSize, SizeF ImageSize)
          {
          PointF selectionTrueOrigin = TranslateZoomPosition(SelectionRect.Location, ContainerSize, ImageSize);
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);

          SizeF selectionTrueSize = new SizeF(SelectionRect.Width / scaleFactor, SelectionRect.Height / scaleFactor);
          return new RectangleF(selectionTrueOrigin, selectionTrueSize);
          }

          public RectangleF TranslateSelectionToZoomedSel(RectangleF SelectionRect, SizeF ContainerSize, SizeF ImageSize)
          {
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);
          RectangleF zoomedSelectionRect = new
          RectangleF(SelectionRect.X * scaleFactor, SelectionRect.Y * scaleFactor,
          SelectionRect.Width * scaleFactor, SelectionRect.Height * scaleFactor);

          PointF imageScaledOrigin = GetImageScaledOrigin(ContainerSize, ImageSize);
          zoomedSelectionRect.Location = new PointF(zoomedSelectionRect.Location.X + imageScaledOrigin.X,
          zoomedSelectionRect.Location.Y + imageScaledOrigin.Y);
          return zoomedSelectionRect;
          }

          public PointF TranslateCoordinatesOrigin(PointF Coordinates, SizeF ContainerSize, SizeF ImageSize)
          {
          PointF imageOrigin = GetImageScaledOrigin(ContainerSize, ImageSize);
          return new PointF(Coordinates.X - imageOrigin.X, Coordinates.Y - imageOrigin.Y);
          }

          public PointF GetImageScaledOrigin(SizeF ContainerSize, SizeF ImageSize)
          {
          SizeF imageScaleSize = GetImageScaledSize(ContainerSize, ImageSize);
          return new PointF((ContainerSize.Width - imageScaleSize.Width) / 2,
          (ContainerSize.Height - imageScaleSize.Height) / 2);
          }

          public SizeF GetImageScaledSize(SizeF ContainerSize, SizeF ImageSize)
          {
          float scaleFactor = GetScaleFactor(ContainerSize, ImageSize);
          return new SizeF(ImageSize.Width * scaleFactor, ImageSize.Height * scaleFactor);

          }
          internal float GetScaleFactor(SizeF Scaled, SizeF Original)
          {
          return (Original.Width > Original.Height) ? (Scaled.Width / Original.Width)
          : (Scaled.Height / Original.Height);
          }
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 19 at 11:52

























          answered Dec 16 '18 at 12:19









          JimiJimi

          8,12241934




          8,12241934













          • Thanks a lot :). I will take a look at both of your answers.

            – techno
            Dec 16 '18 at 12:58











          • Actually also need to do the reverse ie: i have the rectangle coordinates on the original image.When this image is displayed in the picturebox,i need to place the movable frame at the correct position by translating its known position in the original image.

            – techno
            Dec 16 '18 at 17:34











          • @techno See the edit. I've added a selection translator from coordinates relative to the original image to the scaled image (and a sample animation too :). I didn't have not much time, so it's not tested properly, but I've made some slections in different conditions and it looks OK. I'll revise it tomorrow.

            – Jimi
            Dec 16 '18 at 20:37











          • okay...Thanks... :)

            – techno
            Dec 18 '18 at 2:27











          • How do i detect if the control was resized or moved in the picturebox? Currently i use picturebox mouse mouse event. Is there a better way?

            – techno
            Dec 18 '18 at 2:27



















          • Thanks a lot :). I will take a look at both of your answers.

            – techno
            Dec 16 '18 at 12:58











          • Actually also need to do the reverse ie: i have the rectangle coordinates on the original image.When this image is displayed in the picturebox,i need to place the movable frame at the correct position by translating its known position in the original image.

            – techno
            Dec 16 '18 at 17:34











          • @techno See the edit. I've added a selection translator from coordinates relative to the original image to the scaled image (and a sample animation too :). I didn't have not much time, so it's not tested properly, but I've made some slections in different conditions and it looks OK. I'll revise it tomorrow.

            – Jimi
            Dec 16 '18 at 20:37











          • okay...Thanks... :)

            – techno
            Dec 18 '18 at 2:27











          • How do i detect if the control was resized or moved in the picturebox? Currently i use picturebox mouse mouse event. Is there a better way?

            – techno
            Dec 18 '18 at 2:27

















          Thanks a lot :). I will take a look at both of your answers.

          – techno
          Dec 16 '18 at 12:58





          Thanks a lot :). I will take a look at both of your answers.

          – techno
          Dec 16 '18 at 12:58













          Actually also need to do the reverse ie: i have the rectangle coordinates on the original image.When this image is displayed in the picturebox,i need to place the movable frame at the correct position by translating its known position in the original image.

          – techno
          Dec 16 '18 at 17:34





          Actually also need to do the reverse ie: i have the rectangle coordinates on the original image.When this image is displayed in the picturebox,i need to place the movable frame at the correct position by translating its known position in the original image.

          – techno
          Dec 16 '18 at 17:34













          @techno See the edit. I've added a selection translator from coordinates relative to the original image to the scaled image (and a sample animation too :). I didn't have not much time, so it's not tested properly, but I've made some slections in different conditions and it looks OK. I'll revise it tomorrow.

          – Jimi
          Dec 16 '18 at 20:37





          @techno See the edit. I've added a selection translator from coordinates relative to the original image to the scaled image (and a sample animation too :). I didn't have not much time, so it's not tested properly, but I've made some slections in different conditions and it looks OK. I'll revise it tomorrow.

          – Jimi
          Dec 16 '18 at 20:37













          okay...Thanks... :)

          – techno
          Dec 18 '18 at 2:27





          okay...Thanks... :)

          – techno
          Dec 18 '18 at 2:27













          How do i detect if the control was resized or moved in the picturebox? Currently i use picturebox mouse mouse event. Is there a better way?

          – techno
          Dec 18 '18 at 2:27





          How do i detect if the control was resized or moved in the picturebox? Currently i use picturebox mouse mouse event. Is there a better way?

          – techno
          Dec 18 '18 at 2:27


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53800328%2ftranslate-rectangle-position-in-zoom-mode-picturebox%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Liquibase includeAll doesn't find base path

          How to use setInterval in EJS file?

          Petrus Granier-Deferre