| IntroductionOne of the common tasks often performed 
                      to photographic images is resizing. In general, scaling 
                      an image by a certain percentage is quite simple. On the 
                      other hand this might not produce an image that best meets 
                      your needs. Often it is more appropriate to Crop and/or 
                      Pad that image to achieve a standard height or width. Using 
                      some simple techniques, there is an easy way to accomplish 
                      these tasks programmatically using C# and GDI+. In the first step we will load two photographs. 
                      The first photograph has a landscape orientation while the 
                      other is portrait. This will allow for a better demonstration 
                      of how one can resize a photograph of varying sizes and 
                      proportions. string WorkingDirectory = @"C:\Tutorials\ImageResize";
Image imgPhotoVert = Image.FromFile(WorkingDirectory + 
                                @"\imageresize_vert.jpg");
Image imgPhotoHoriz = Image.FromFile(WorkingDirectory + 
                               @"\imageresize_horiz.jpg");
Image imgPhoto = null;Example # 1 - Scale by 
                      percentIn this example we will demonstrate a simple 
                      method of scaling a photograph by a specified percentage. 
                      Both the width and height will be scaled uniformly. imgPhoto = ScaleByPercent(imgPhotoVert, 50);
imgPhoto.Save(WorkingDirectory + 
    @"\images\imageresize_1.jpg", ImageFormat.Jpeg);
imgPhoto.Dispose();
....
static Image ScaleByPercent(Image imgPhoto, int Percent)
{
    float nPercent = ((float)Percent/100);
    int sourceWidth = imgPhoto.Width;
    int sourceHeight = imgPhoto.Height;
    int sourceX = 0;
    int sourceY = 0;
    int destX = 0;
    int destY = 0; 
    int destWidth  = (int)(sourceWidth * nPercent);
    int destHeight = (int)(sourceHeight * nPercent);
    Bitmap bmPhoto = new Bitmap(destWidth, destHeight, 
                             PixelFormat.Format24bppRgb);
    bmPhoto.SetResolution(imgPhoto.HorizontalResolution, 
                            imgPhoto.VerticalResolution);
    Graphics grPhoto = Graphics.FromImage(bmPhoto);
    grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
    grPhoto.DrawImage(imgPhoto, 
        new Rectangle(destX,destY,destWidth,destHeight),
        new Rectangle(sourceX,sourceY,sourceWidth,sourceHeight),
        GraphicsUnit.Pixel);
    grPhoto.Dispose();
    return bmPhoto;
}
 Scaled to 50% of original size In the above example we define a series 
                      of variables that are used in the process of scaling the 
                      image. sourceWidth,sourceHeight,sourceX,sourceYare used to build up a source rectangle structure. This 
                      structure specifies the portion of the source image object 
                      to draw. In our example we want the entire image, so our 
                      source rectangle will have the following values:new 
                      Rectangle(0,0,370,450). destWidth,destHeight,destX,destYare used to build a destination rectangle structure. This 
                      structure specifies the location and size of the drawn image. 
                      The image is scaled to fit this rectangle. ThedestWidthanddestHeightare calculated by 
                      multiplying thesourceWidthandsourceHeightby the percentage we want it scaled by. The result is aBitmapwith the new width and height 
                      and a destination rectangle with the following values:new 
                      Rectangle(0,0,185,225).
 Example #2 - Scale to a 
                      fixed sizeA very common task used when creating images 
                      for a web site is to resize those images to have a fixed 
                      width and height. Often when displaying a list of data, 
                      it is beneficial to have any columns that contain images 
                      occupy identical dimensions. Since images will have varying 
                      orientations it will be necessary to fit either the width 
                      or height, then pad the opposite dimension with filler. imgPhoto = FixedSize(imgPhotoVert, 300, 300);
imgPhoto.Save(WorkingDirectory + 
    @"\images\imageresize_3.jpg", ImageFormat.Jpeg);
imgPhoto.Dispose();
....
static Image FixedSize(Image imgPhoto, int Width, int Height)
{
    int sourceWidth = imgPhoto.Width;
    int sourceHeight = imgPhoto.Height;
    int sourceX = 0;
    int sourceY = 0;
    int destX = 0;
    int destY = 0; 
    float nPercent = 0;
    float nPercentW = 0;
    float nPercentH = 0;
    nPercentW = ((float)Width/(float)sourceWidth);
    nPercentH = ((float)Height/(float)sourceHeight);
    if(nPercentH < nPercentW)
    {
        nPercent = nPercentH;
        destX = System.Convert.ToInt16((Width - 
                      (sourceWidth * nPercent))/2);
    }
    else
    {
        nPercent = nPercentW;
        destY = System.Convert.ToInt16((Height - 
                      (sourceHeight * nPercent))/2);
    }
    int destWidth  = (int)(sourceWidth * nPercent);
    int destHeight = (int)(sourceHeight * nPercent);
    Bitmap bmPhoto = new Bitmap(Width, Height, 
                      PixelFormat.Format24bppRgb);
    bmPhoto.SetResolution(imgPhoto.HorizontalResolution, 
                     imgPhoto.VerticalResolution);
    Graphics grPhoto = Graphics.FromImage(bmPhoto);
    grPhoto.Clear(Color.Red);
    grPhoto.InterpolationMode = 
            InterpolationMode.HighQualityBicubic;
    grPhoto.DrawImage(imgPhoto, 
        new Rectangle(destX,destY,destWidth,destHeight),
        new Rectangle(sourceX,sourceY,sourceWidth,sourceHeight),
        GraphicsUnit.Pixel);
    grPhoto.Dispose();
    return bmPhoto;
}In the above example it is our desire to 
                      create an image with a width of 300 and a height of 300. 
                      The first step in accomplishing this is to determine the 
                      smallest possible percent that we can shrink this image, 
                      while making sure to fill the maximum height and width. nPercentW = ((float)Width/(float)sourceWidth);
nPercentH = ((float)Height/(float)sourceHeight);
if(nPercentH < nPercentW)
{
    nPercent = nPercentH;
    destX = (int)((Width - (sourceWidth * nPercent))/2);
}
else
{
    nPercent = nPercentW;
    destY = (int)((Height - (sourceHeight * nPercent))/2);
}
 To do this we will calculate both a height 
                      percentage and a width percentage and check which is smaller. 
                      nPercentW=.8108 whilenPercentH=.6666. 
                      Choosing the smaller percentage guarantees that none of 
                      the image will be cropped. Since height is the smaller reduction, 
                      this will be our maximum percent to scale the original image. When this percent is applied to the width, 
                      we end up with a width equal to 247. Our desired destWidthwas 300, so we will need to pad each side of the image with 
                      27 additional pixels. This padding is accomplished by setting 
                      thedestX=27. This will shift the 
                      newly scaled image to the right 27 pixels. Using the desired nPercentanddestX, we can build up the appropriate 
                      destinationRectangleand draw the 
                      new image. Example #3 - Scale with 
                      croppingThe last resizing technique we will discuss 
                      is the process of cropping an image. This technique follows 
                      a similar methodology as the previous fixed size example 
                      with a few exceptions. imgPhoto = Crop(imgPhotoVert, 300, 300, AnchorPosition.Bottom);
imgPhoto.Save(WorkingDirectory + 
       @"\images\imageresize_4.jpg", ImageFormat.Jpeg);
imgPhoto.Dispose();
....
static Image Crop(Image imgPhoto, int Width, 
                    int Height, AnchorPosition Anchor)
{
    int sourceWidth = imgPhoto.Width;
    int sourceHeight = imgPhoto.Height;
    int sourceX = 0;
    int sourceY = 0;
    int destX = 0;
    int destY = 0;
    float nPercent = 0;
    float nPercentW = 0;
    float nPercentH = 0;
    nPercentW = ((float)Width/(float)sourceWidth);
    nPercentH = ((float)Height/(float)sourceHeight);
    if(nPercentH < nPercentW)
    {
        nPercent = nPercentW;
        switch(Anchor)
        {
            case AnchorPosition.Top:
                destY = 0;
                break;
            case AnchorPosition.Bottom:
                destY = (int)
                    (Height - (sourceHeight * nPercent));
                    break;
            default:
                destY = (int)
                    ((Height - (sourceHeight * nPercent))/2);
                break;
        }
    }
    else
    {
        nPercent = nPercentH;
        switch(Anchor)
        {
            case AnchorPosition.Left:
                destX = 0;
                break;
            case AnchorPosition.Right:
                destX = (int)
                  (Width - (sourceWidth * nPercent));
                break;
            default:
                destX = (int)
                  ((Width - (sourceWidth * nPercent))/2);
                break;
        } 
    }
    int destWidth  = (int)(sourceWidth * nPercent);
    int destHeight = (int)(sourceHeight * nPercent);
    Bitmap bmPhoto = new Bitmap(Width, 
            Height, PixelFormat.Format24bppRgb);
    bmPhoto.SetResolution(imgPhoto.HorizontalResolution, 
            imgPhoto.VerticalResolution);
    Graphics grPhoto = Graphics.FromImage(bmPhoto);
    grPhoto.InterpolationMode = 
            InterpolationMode.HighQualityBicubic;
    grPhoto.DrawImage(imgPhoto, 
        new Rectangle(destX,destY,destWidth,destHeight),
        new Rectangle(sourceX,sourceY,sourceWidth,sourceHeight),
        GraphicsUnit.Pixel);
    grPhoto.Dispose();
    return bmPhoto;
}When cropping an image you have 5 choices 
                      as to how one decides, what part of the image to crop. We 
                      refer to this as how one anchors the image. Top, bottom, 
                      and center are appropriate when cropping an image's height 
                      where as left, right and center are appropriate for width. 
                      (There are more, but for the purpose of this example we 
                      will focus in these 5.) Similar to example #2, the first thing 
                      we need to do is determine a height percentage and a width 
                      percentage that gets us to the desired dimensions. Since 
                      our desired dimensions are 300x300, we end up with the same 
                      percentages as in the previous example. Once again we will 
                      compare the two, but this time we will choose the larger 
                      of the two percentages. (nPercentW= .8108) if(nPercentH < nPercentW)
{
    nPercent = nPercentW;
    switch(Anchor)
    {
        case AnchorPosition.Top:
 destY = 0;
 break;
        case AnchorPosition.Bottom:
 destY = (int)(Height - (sourceHeight * nPercent));
 break;
        default:
 destY = (int)((Height - (sourceHeight * nPercent))/2);
 break;
    }
}
 Image anchored top 
 Image anchored center 
 Image anchored bottom By using 3 different destYvalues, we can achieve the 3 different ways to crop the 
                      image. If our source image would have had a landscape orientation, 
                      then left, right and center would have been appropriate 
                      anddestXwould have been used to 
                      achieve a crop of the image's width. One last thing...In all of the examples, we called both 
                      the SetResolutionandInterpolationModeprior todrawImage.SetResolutiondoes just as the name implies. In these examples, we carry 
                      over the original image's resolution by setting this property 
                      equal toimgPhoto.HorizontalResolution,imgPhoto.VerticalResolution. bmPhoto.SetResolution(imgPhoto.HorizontalResolution, 
                                 imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;Interpolation refers to how data is interpolated 
                      between endpoints. In its simplest form, to interpolate 
                      is to estimate a missing value by taking an average of known 
                      values at neighboring points. Below is the graphical representation 
                      of three different approaches to interpolation. In general the bicubic interpolation is 
                      used when more accuracy is desired than the bilinear interpolation. 
 Bicubic interpolation 
 Bilinear interpolation 
 Nearest-neighbor interpolation That's it! Compile the project, run it, 
                      and see what happens! The code is fairly straightforward. 
                      If it all makes sense, then these resizing techniques can 
                      be used to scale virtually any image. |