marți, 2 august 2011

A MonoTouch class for resize maintaining aspect ratio or crop your images

Hy guys,

I wrote a c# class for a personal project, and I'm sure it will be useful for you to. Very often we need to quickly resize an UIImage, using Thumb Resize maintaining aspect ratio or Crop Resize...

A quick example to crop and resize an image from 768x507 to 300x300:
//load a test image, with size: 768x507
UIImage img = UIImage.FromFile("test.jpg");
//initiate the resizer class
ImageResizer resizer = new ImageResizer(img);
//crop resize 
resizer.CropResize( 300,300 );
//and that's it! The image is resized & croped to exactly 300x300
UIImage croppedImage = resizer.ModifiedImage;

Or resize maintaining ratio to a maximum of 200x200:
//load a test image, with size: 768x507
UIImage img = UIImage.FromFile("test.jpg");
//initiate the resizer class
ImageResizer resizer = new ImageResizer(img);
//crop resize 
resizer.RatioResize( 200,200 ); //now it has 200x132
//and that's it! 
UIImage croppedImage = resizer.ModifiedImage;

Also you can scale it to 120% for example
//load a test image, with size: 768x507
UIImage img = UIImage.FromFile("test.jpg");
//initiate the resizer class
ImageResizer resizer = new ImageResizer(img);
//crop resize 
resizer.Scale( 120 ); //now it has 922x608
//and that's it! 
UIImage croppedImage = resizer.ModifiedImage;

So, here it is!

using System;
using MonoTouch.UIKit;
using System.Drawing;
using MonoTouch.CoreGraphics;
namespace Test
{
 public enum CropPosition
 {
  Start, Center, End
 }
 
 public class ImageResizer
 {
  UIImage initialImage  = null;
  UIImage modifiedImage = null;
  
  public ImageResizer ( UIImage image )
  {
   this.initialImage         = image;
   this.modifiedImage = image;
  }
  
  
  /// <summary>
  /// strech resize
  /// </summary>
  public void Resize( float width, float height )
  {
   UIGraphics.BeginImageContext( new SizeF( width, height ) );
   //
   modifiedImage.Draw( new RectangleF( 0,0, width, height ) );
   modifiedImage = UIGraphics.GetImageFromCurrentImageContext();
   //
   UIGraphics.EndImageContext();
  }
  
  public void RatioResizeToWidth( float width )
  {
   Console.WriteLine("resize to width: " + width  );
   var cur_width = modifiedImage.Size.Width;
   if( cur_width > width )
   {
    var ratio  = width / cur_width;
    var height = modifiedImage.Size.Height * ratio;
    //resize
    Resize( width, height );
   }
  }
  
  public void RatioResizeToHeight( float height )
  {
   Console.WriteLine("resize to height: " + height  );
   var cur_height = modifiedImage.Size.Height;
   if( cur_height > height )
   {
    var ratio = height / cur_height;
    var width = modifiedImage.Size.Width * ratio;
    //
    Resize( width, height );
   }
  }
  
  /// <summary>
  /// resize maintaining ratio
  /// </summary>
  public void RatioResize( float max_width, float max_height )
  {
   if( max_width > max_height )
   {
    RatioResizeToWidth ( max_width  );
    RatioResizeToHeight( max_height );
   }
   else
   {
    RatioResizeToHeight( max_height );
    RatioResizeToWidth ( max_width  );
   }
  }
  
  /// <summary>
  /// scaling the image with a given procent value
  /// </summary>
  public void Scale( float procent )
  {
   var width  = modifiedImage.Size.Width  * (procent / 100);
   var height = modifiedImage.Size.Height * (procent / 100);
   Resize( width, height );
  }
  
  /// <summary>
  /// default crop resize, set on center
  /// </summary>
  public void CropResize( float width, float height )
  {
   CropResize(width, height, CropPosition.Center );
  }
  
  /// <summary>
  /// resize and crop to a specific location
  /// </summary>
  public void CropResize( float width, float height, CropPosition position )
  {
   SizeF ImgSize = modifiedImage.Size;
   //
   if( ImgSize.Width  < width  ) width  = ImgSize.Width;
   if( ImgSize.Height < height ) height = ImgSize.Height;
   //
   float crop_x = 0;
   float crop_y = 0;
   if( ImgSize.Width / width < ImgSize.Height / height )
   {
    //scad din width
    RatioResizeToWidth( width );
    ImgSize = modifiedImage.Size;
    //compute crop_y
    if( position == CropPosition.Center ) crop_y = (ImgSize.Height / 2) - (height / 2);
    if( position == CropPosition.End    ) crop_y = ImgSize.Height - height;
   }
   else
   {
    //change height
    RatioResizeToHeight( height );
    ImgSize = modifiedImage.Size;
    //calculeaza crop_x
    if( position == CropPosition.Center ) crop_x = (ImgSize.Width / 2) - (width / 2);
    if( position == CropPosition.End    ) crop_x = ImgSize.Width - width;
   }
   //create new contect
   UIGraphics.BeginImageContext( new SizeF( width, height ) );
   CGContext context =  UIGraphics.GetCurrentContext();
   //crops the new context to the desired height and width
   RectangleF clippedRect = new RectangleF( 0, 0, width, height );
   context.ClipToRect(clippedRect);
   //draw my image on the context
   RectangleF drawRect = new RectangleF( -crop_x, -crop_y, ImgSize.Width, ImgSize.Height );
   modifiedImage.Draw( drawRect );
   //save the context in modifiedImage
   modifiedImage = UIGraphics.GetImageFromCurrentImageContext();
   //close the context
   UIGraphics.EndImageContext();
   
  }
 

  public UIImage InitialImage 
  {
   get 
   {
    return this.initialImage;
   }
  }

  public UIImage ModifiedImage 
  {
   get 
   {
    return this.modifiedImage;
   }
  }
 }
}