Introduction
The standard input with type file allows us to upload files. One of the usually uploaded file types is images. And it is very useful when you can preview images before upload and moreover define certain area of image that should be uploaded. Here, I will demonstrate how to create multi image uploader with crop using ASP.NET MVC.
Background
To help us preview images and apply crop, I will use my own jQuery plugin jquery.multiuploader.crop.js which will do all UI work for us.
Using the Code
To create UI for uploader, simply define div
element in your markup and apply plugin jquery.multiuploader.crop.js to it like so:
$('#myUploader').imageUploaderCut({
proceedCallBack: uploadCallBack
});
The UI part will only return Json with array of objects as parameter to call back function. Each object will contain necessary information to upload the cropped image.
var o = {
'Content': img.attr('src'),
'FileName': aperture.attr('data-filename'),
'ContentLenght': aperture.attr('data-filesize'),
'ImgWidth': img.width(),
'ImgHeight': img.height(),
'CropX': Math.abs(parseInt(img.css('left'))),
'CropY': Math.abs(parseInt(img.css('top'))),
'CropWidth': aperture.width(),
'CropHeight': aperture.height()
};
And .NET model:
public class UploadFileModel {
public string Content { get; set; }
public string FileName { get; set; }
public int ContentLenght { get; set; }
public float ImgWidth { get; set; }
public float ImgHeight { get; set; }
public float CropX { get; set; }
public float CropY { get; set; }
public int CropWidth { get; set; }
public int CropHeight { get; set; }
}
Once all manipulation with images are done and we ready to post data to server, we will use this code:
function uploadCallBack(jsonString) {
$.ajax({
url: '/Home/UploadToServer',
type: 'POST',
dataType: 'json',
data: jsonString,
contentType: 'application/json; charset=utf-8',
success: function(data, event) {
},
error: function (data, event) {
}
});
}
On the server side, we will define action which accepts list of uploaded images:
[HttpPost]
[JsonFilter( Param = "widgets", JsonDataType = typeof (List<UploadFileModel>) )]
public JsonResult UploadToServer( List<UploadFileModel> images )
Here, you can see custom attribute with the help of which I deserialize Json to Model object.
public class JsonFilter : ActionFilterAttribute {
public string Param { get; set; }
public Type JsonDataType { get; set; }
public override void OnActionExecuting( ActionExecutingContext filterContext ) {
string inputContent;
filterContext.HttpContext.Request.InputStream.Position = 0;
using (var sr = new StreamReader(filterContext.HttpContext.Request.InputStream)) {
inputContent = sr.ReadToEnd();
}
var result = JsonConvert.DeserializeObject(inputContent, JsonDataType);
filterContext.ActionParameters[Param] = result;
}
}
Download the attached source code to see how exactly I've done crop and save cropped images.
Points of Interest
While creating this sample uploader, I dug a little bit into school course of geometry to learn how to properly resize image and keep the ratio between width and height.