Search code examples
c#.netbitmapsystem.drawing

Cropping a Bitmap to 1:1 Aspect Ratio


I have Bitmaps with an aspect ratios like the following or may be in any aspect ratio..

enter image description here

enter image description here

When the user specifies an option i need a way to crop out the surrounding portions from these images so that an Image with 1:1 Aspect ratio is produced. Like this

enter image description here

I think i will take the center point in these images and crop out the sides..

I have found this method in the web platform.. but Bitmap does not have a Cropmethod

 public static WebImage BestUsabilityCrop(WebImage image, decimal targetRatio)
        {
            decimal currentImageRatio = image.Width / (decimal)image.Height;
            int difference;

            //image is wider than targeted
            if (currentImageRatio > targetRatio)
            {
                int targetWidth = Convert.ToInt32(Math.Floor(targetRatio * image.Height));
                difference = image.Width - targetWidth;
                int left = Convert.ToInt32(Math.Floor(difference / (decimal)2));
                int right = Convert.ToInt32(Math.Ceiling(difference / (decimal)2));
                image.Crop(0, left, 0, right);
            }
            //image is higher than targeted
            else if (currentImageRatio < targetRatio)
            {
                int targetHeight = Convert.ToInt32(Math.Floor(image.Width / targetRatio));
                difference = image.Height - targetHeight;
                int top = Convert.ToInt32(Math.Floor(difference / (decimal)2));
                int bottom = Convert.ToInt32(Math.Ceiling(difference / (decimal)2));
                image.Crop(top, 0, bottom, 0);
            }
            return image;
        }

Please advice a way to tackle this issue.


Solution

  • You can use something like this:

    public static Image Crop(Image source)
    {
        if (source.Width == source.Height) return source;
        int size = Math.Min(source.Width, source.Height);
        var sourceRect = new Rectangle((source.Width - size) / 2, (source.Height - size) / 2, size, size);
        var cropped = new Bitmap(size, size);
        using (var g = Graphics.FromImage(cropped))
            g.DrawImage(source, 0, 0, sourceRect, GraphicsUnit.Pixel);
        return cropped;
    }
    

    This does cropping from the center. If you want to crop from bottom/right, then just use var sourceRect = new Rectangle(0, 0, size, size);.