title: Cropping an image to a "perfect" square like native Photos app
body: <p>Whilst working on a functionality for viewing embedded images that get fetched from one of our servers, one of the requirements is to make an overview page, where all images are displayed, in a fasion like the iOS Native Photos App (square tiles, in rows of 4/5 and when tapped, displays the image screen-wide.</p>
  
  <p>This has been successfully implemented, except that the images were morphed (image aspects were never taken into account). Thus, they have asked me to devise a method to crop the image, so the original aspect stays unchanged.</p>
  
  <p>In order to do this, I was thinking of first resizing the image until the width reaches the max width I want it to be ((screenwidth - 10) / 4 - 5). </p>
  
  <ul>
  <li>If the height of the image is smaller than the width, I set the height to be equal to the width, and crop the width accordingly (with aspect unchanged).</li>
  <li>If the height of the image is greater than the width, I just want to crop the height.</li>
  </ul>
  
  <p>This is the method I am currently using:</p>
  
  <pre><code>//Images is an array/List with base64 strings
  foreach (var image in Images)
  {
      UIImage imageToAdd = UIImage.LoadFromData(NSData.FromArray(Convert.FromBase64String(image.Content)));
  
      var width = imageToAdd.Size.Width;
      var height = imageToAdd.Size.Height;
  
      //GlobalSupport.ScreenWidth is a static variable that contains the actual screensize
      var newWidth = (GlobalSupport.ScreenWidth - 10) / 4 - 5;
  
      var newHeight = height * newWidth / width;
  
      var widthToCrop = 0.0f;
      var heightToCrop = 0.0f;
  
      //If the new height is smaller than the new width, make the new height equal to the new width, and modify the new width accordingly.
      if (newHeight &lt; newWidth)
      {
          newHeight = newWidth;
          newWidth = width * newHeight / height;
  
          widthToCrop = newWidth - newHeight;
      }
      //Or, if the new height is greater than the new width, just crop the height.
      else if (newHeight &gt; newWidth)
      {
          heightToCrop = newHeight - newWidth;
      }
  
      UIGraphics.BeginImageContext(new SizeF(newWidth, newHeight));
      var cropRectangle = new RectangleF(-widthToCrop, -heightToCrop, newWidth, newHeight);
      imageToAdd.Draw(cropRectangle);
      imageToAdd = UIGraphics.GetImageFromCurrentImageContext();
      UIGraphics.EndImageContext();
  
      UIButton btnToAdd = new UIButton(new RectangleF(-widthToCrop, -heightToCrop, newWidth, newHeight));
  
      btnToAdd.SetBackgroundImage(imageToAdd, UIControlState.Normal);
  
      btnToAdd.TouchUpInside += (sender, e) =&gt;
      {
          Task.Factory.StartNew(() =&gt;
              {
                  //Displays a loading spinner
                  GlobalSupport.EnableLoadingOverlay(true, NSBundle.MainBundle.LocalizedString("txtOneMoment", "", ""));
              }).ContinueWith(task =&gt; InvokeOnMainThread(() =&gt;
                  {
                      //Navigate to the full-screen image viewer
                      this.NavigationController.PushViewController(
                          new VCDCMPhotoDetails(
                              UIImage.LoadFromData(
                                  NSData.FromArray(
                                      Convert.FromBase64String(image.Content)))), true);
  
                      GlobalSupport.EnableLoadingOverlay(false, "");
                  }));
      };
  
      //Add btn to the scrollable view's children
      scrollView.AddSubview(btnToAdd);
  }
  </code></pre>
  
  <p>This method works great, except for one thing: if the <code>new height</code> is smaller than the <code>new width</code>, the <code>new height</code> and <code>new width</code> successfully get modified, but after the <code>ImageToAdd.Draw(RectangleF)</code> the <code>Size</code> of the <code>ImageToAdd</code> still has the <code>new width</code> value, instead of the cropped width (that is, if I can assume that, if I draw an image with -20 as its x-value, the width gets modified with -20 as well).</p>
  
  <p>I don't know if this is the right way to do it. If it isn't, then all help is welcome! If this is the right way to do it, but I'm missing something, please let me know! Thanks in advance!</p>
  
  <p>When cropping the image, the x-coordinate is equal to the width of the image, minus the max width of a thumbnail: <a href="http://i.stack.imgur.com/uNm7k.png" rel="nofollow">http://i.stack.imgur.com/uNm7k.png</a></p>
  
  <p>After cropping, the image still had the original new width, instead of the cropped width: <a href="http://i.stack.imgur.com/rabeY.png" rel="nofollow">http://i.stack.imgur.com/rabeY.png</a></p>
  
  <p>The resulting grid of images: <a href="http://i.stack.imgur.com/opo2f.jpg" rel="nofollow">http://i.stack.imgur.com/opo2f.jpg</a></p>