Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to crop an image using C#?

Check out this link: http://www.switchonthecode.com/tutorials/csharp-tutorial-image-editing-saving-cropping-and-resizing

private static Image cropImage(Image img, Rectangle cropArea)
{
   Bitmap bmpImage = new Bitmap(img);
   return bmpImage.Clone(cropArea, bmpImage.PixelFormat);
}

You can use Graphics.DrawImage to draw a cropped image onto the graphics object from a bitmap.

Rectangle cropRect = new Rectangle(...);
Bitmap src = Image.FromFile(fileName) as Bitmap;
Bitmap target = new Bitmap(cropRect.Width, cropRect.Height);

using(Graphics g = Graphics.FromImage(target))
{
   g.DrawImage(src, new Rectangle(0, 0, target.Width, target.Height), 
                    cropRect,                        
                    GraphicsUnit.Pixel);
}

Simpler than the accepted answer is this:

public static Bitmap cropAtRect(this Bitmap b, Rectangle r)
{
    Bitmap nb = new Bitmap(r.Width, r.Height);
    using (Graphics g = Graphics.FromImage(nb))
    {
        g.DrawImage(b, -r.X, -r.Y);
        return nb;
    }
}

and it avoids the "Out of memory" exception risk of the simplest answer.

Note that Bitmap and Graphics are IDisposable hence the using clauses.

EDIT: I find this is fine with PNGs saved by Bitmap.Save or Paint.exe, but fails with PNGs saved by e.g. Paint Shop Pro 6 - the content is displaced. Addition of GraphicsUnit.Pixel gives a different wrong result. Perhaps just these failing PNGs are faulty.


use bmp.SetResolution(image.HorizontalResolution, image .VerticalResolution);

this may be necessary to do even if you implement best answer here especially if your image is real great and resolutions are not exactly 96.0

My test example:

    static Bitmap LoadImage()
    {
        return (Bitmap)Bitmap.FromFile( @"e:\Tests\d_bigImage.bmp" ); // here is large image 9222x9222 pixels and 95.96 dpi resolutions
    }

    static void TestBigImagePartDrawing()
    {
        using( var absentRectangleImage = LoadImage() )
        {
            using( var currentTile = new Bitmap( 256, 256 ) )
            {
                currentTile.SetResolution(absentRectangleImage.HorizontalResolution, absentRectangleImage.VerticalResolution);

                using( var currentTileGraphics = Graphics.FromImage( currentTile ) )
                {
                    currentTileGraphics.Clear( Color.Black );
                    var absentRectangleArea = new Rectangle( 3, 8963, 256, 256 );
                    currentTileGraphics.DrawImage( absentRectangleImage, 0, 0, absentRectangleArea, GraphicsUnit.Pixel );
                }

                currentTile.Save(@"e:\Tests\Tile.bmp");
            }
        }
    }