ASP.NET Image / Photo Cropper in C#

You can skip to the demo by clicking here
You can download the source code by clicking here

For my current project I needed to create some logic for users to upload an image...only problem was the image had to be of a fixed size, and therefore aspect ratio.  Enter the need for an image cropper.  You've seen them before on a number of sites, like linkedIn, facebook, and everywhere else.  I began my journey of trying to find one.  There are a fair amount of tutorials/code snippets on the web that illustrate how to do this from the client-side using JavaScript.  I also came across some articles on codeProject and such as that explained how to crop images on the server-side.  What I couldn't find was an article that tied the client-side JavaScript and the server-side cropping together.  And that's exactly what this article is.

Before I get into the fun stuff...the process is really as follows
1 - User crops image on the client-side
2 - Track the X & Y coordinates, as well as the height and width of the box the user drags over the image
3 - Use the server-side code to actually crop the image [providing the coordinates and dimensions from step 2]

That's really about it.  I should also say that all the JavaScript I used was obtained from http://www.defusion.org.uk/code/javascript-image-cropper-ui-using-prototype-scriptaculous/

It's a slick piece of code - please check out the site for updates (I believe version 2 is a work in progress) and to donate.

As for the .NET code (C#) - you can obtain it from here:
You'll need to make sure that you provide write permissions to the directory where you want to save the new, cropped image.  Check out line 19, where I set the value for the CROPPED_SAMPLE_PHOTO_URL constant string.

You can see a demo here: http://www.sanjayu.qsh.es/PhotoCropper.aspx
Note: The demo and the download work slightly differently.  This is mainly because I'm saving the image to a session variable for the demo, but using the file system in the download.

As for the code, the heart of it is really the CropImageFile method, where you re-draw the image taking into account our coordinates and dimensions. 
protected byte[] CropImageFile(byte[] imageFile, int targetW, int targetH, int targetX, int targetY)
    {
        MemoryStream imgMemoryStream = new MemoryStream();
        System.Drawing.Image imgPhoto = System.Drawing.Image.FromStream(new MemoryStream(imageFile));

        Bitmap bmPhoto = new Bitmap(targetW, targetH, PixelFormat.Format24bppRgb);
        bmPhoto.SetResolution(72, 72);
  
        Graphics grPhoto = Graphics.FromImage(bmPhoto);
        //Adjust settings to make this as high-quality as possible 
        grPhoto.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
        grPhoto.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;

        try
        {
            grPhoto.DrawImage(imgPhoto, new Rectangle(0, 0, targetW, targetH),
                                targetX, targetY, targetW, targetH, GraphicsUnit.Pixel);
            //Only JPG format for this demo
            bmPhoto.Save(imgMemoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);
        }
        catch (Exception e)
         ... //removed code to stay concise
        return imgMemoryStream.GetBuffer();
    }

Enjoy!
kick it on DotNetKicks.com

Print | posted @ Monday, September 08, 2008 12:21 AM

Comments on this entry:

Gravatar # re: ASP.NET Image / Photo Cropper in C#
by b2b at 9/8/2008 10:09 AM

Sanjay, it was exactly what I was looking for! Great tip.
Gravatar # re: ASP.NET Image / Photo Cropper in C#
by Rajesh at 9/18/2008 2:36 AM

Sanjay really great work....i was exactly looking for the same. since long back. and luckily to i got from you.thankyou very much.
Gravatar # re: ASP.NET Image / Photo Cropper in C#
by Amit Parmar at 11/6/2008 4:43 AM

Thank you Sanjay
I am looking for same function since long time
now i have find this is really working good and Smooth thank
Gravatar # re: ASP.NET Image / Photo Cropper in C#
by Muhammad Hassan at 12/17/2008 11:00 AM

Thank you very much for such a great great code snipt I was searching for it for a whole day and in the mid night I got your code.

I did my stuff too with the same Javascript file before in the day, but at the end you code us much easier to go with

Thank you again
Gravatar # re: ASP.NET Image / Photo Cropper in C#
by zatar at 1/11/2009 9:17 AM

Great thanks to u Sanjay , that's help me perfectly

if you don't mind i have question:
when i run it i got exception in" Reading the original photo in as a byte array"

in that row:
byte[] rawData = File.ReadAllBytes(ORIG_SAMPLE_PHOTO_URL);

(telling me that Could not find a part of the path 'C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\~\photos\TheDog.jpg'.)

thanx again
Gravatar # re: ASP.NET Image / Photo Cropper in C#
by SanjayU at 1/11/2009 1:30 PM

Zatar,
I believe you just need to ensure the value of the ORIG_SAMPLE_PHOTO_URL const variable is set to the correct location on your HD. You may want to try a simple file path to ensure there isn't a problem with that specific location or spaces in the file path. For example, place a photo in "C:\Pictures\".

HTH,
Sanjay
Gravatar # re: ASP.NET Image / Photo Cropper in C#
by zatar at 1/12/2009 4:59 AM

sanjay,
first ,realy thanks for your attention ..
the value of " ORIG_SAMPLE_PHOTO_URL " i think it set correctly because we i run the project it work properly-seen the picture- .. then i make my cropping then when i click the "crop image " btn i got that error in that line

thanx
Gravatar # re: ASP.NET Image / Photo Cropper in C#
by Patrik at 1/15/2009 12:51 PM

Zatar,

I had the same problem. Made it work by using these const:
private const string ORIG_SAMPLE_PHOTO_URL = "~/photos/TheDog.jpg";
private const string CROPPED_SAMPLE_PHOTO_URL = "~/photos/TheDogCropped.jpg";

and modifying the code like so
in btnCrop_Click:
byte[] rawData = File.ReadAllBytes(HttpContext.Current.Server.MapPath(ORIG_SAMPLE_PHOTO_URL));

and in writeByteArrayToFile:
using (BinaryWriter binWriter =
new BinaryWriter(File.Open(HttpContext.Current.Server.MapPath(CROPPED_SAMPLE_PHOTO_URL), FileMode.Create)))
Gravatar # re: ASP.NET Image / Photo Cropper in C#
by HS at 2/11/2009 3:23 PM

Hello,

I was wondering how I can disable the resizing of the crop window basically having it one size and non-resizeable?

Thank you.
Gravatar # re: ASP.NET Image / Photo Cropper in C#
by SanjayU at 2/11/2009 4:31 PM

HS,
You'll need to set the minWidth/maxWidth and minHeight/maxHeight arguments to be the same value. This will prevent the user from changing the size of the area to be cropped.

For example:

Event.observe(
window,
'load',
function() {
new Cropper.ImgWithPreview(
'SomeImgId',
{
minWidth: 67,
maxWidth: 67,
minHeight: 86,
maxHeight: 86,
ratioDim: { x: 67, y: 86 },
onEndCrop: onEndCrop,
displayOnInit: true,
previewWrap: 'previewArea'
}
)
}
);

Hope this helps!
Gravatar # re: ASP.NET Image / Photo Cropper in C#
by kunal at 3/4/2009 12:09 AM

When I attach an image to asp image control and as it is very big in size, i haveset its height and width to 500, then crop doesnt work.. any idea?
Gravatar # re: ASP.NET Image / Photo Cropper in C#
by Ritesh at 4/2/2009 1:55 AM

Really nice work, I was looking for something like this. It gave me the whole idea of image optimization. Many Thanks.
Gravatar # re: ASP.NET Image / Photo Cropper in C#
by sv at 4/2/2009 12:29 PM

what about:

Bitmap bmpImage = new Bitmap(img);
Bitmap bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat);
return (Image)(bmpCrop);

Gravatar # re: ASP.NET Image / Photo Cropper in C#
by dan at 4/3/2009 1:37 PM

Awesome. Thanks.

Your comment:

Title:
Name:
Email:
Website:
 
Italic Underline Blockquote Hyperlink
 
 
 
Twitter