Hi I'm trying to upload a image file to the server.I have used jCrop to crop the image before uploading and used canvas to get the cropped image coordinates.I have included controller and jsp files .But I'm not able to send formdata using ajax.
AppController.java
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public String handleFormUpload(@RequestParam("file") MultipartFile file, ModelMap model) throws IOException{
if (!file.isEmpty()) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String name = auth.getName(); //get logged in username
BufferedImage src = ImageIO.read(new ByteArrayInputStream(file.getBytes()));
File destination = new File("/home/me/Desktop/"+name+".png");
model.addAttribute("username", name);
// something like C:/Users/tom/Documents/nameBasedOnSomeId.png
ImageIO.write(src, "png", destination);
//Save the id you have used to create the file name in the DB. You can retrieve the image in future with the ID.
}else {
System.out.println("file is empty");
}
return "prefs";
}
prefs.jsp
<script type="text/javascript">
$(function(){
$('.majorpoints').click(function(){
$(this).find('.hiders').slideToggle();
});
$("#imgInp").change(function(){
var c = $('.cropArea').Jcrop({
onSelect: updateCoords,
bgOpacity: .4,
setSelect: [ 100, 100, 50, 50 ],
aspectRatio: 16 / 9
});
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#blah').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
readURL(this);
});
$('#btnCrop').click(function () {
var x1 = $('#x').val();
var y1 = $('#y').val();
var width = $('#w').val();
var height = $('#h').val();
var canvas = $("#canvas")[0];
alert(x1+""+y1+""+""+width+""+height);
var context = canvas.getContext('2d');
var img = new Image();
img.onload = function () {
canvas.height = height;
canvas.width = width;
context.drawImage(img, x1, y1, width, height, 0, 0, width, height);
$("#imgInp").val(canvas.toDataURL("image/jpeg"));
};
var data = new FormData();
data.append('file', dataURItoBlob(canvas.toDataURL("image/jpeg")));
$.ajax({
url: 'upload',
data: data,
contentType: false,
processData: false,
type: 'POST',
success: function(data){
alert(data);
}
});
img.src = $('#blah').attr('src');
});
});
function dataURItoBlob(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type:mimeString});
}
function updateCoords(c)
{
console.log(c);
$('#x').val(c.x);
$('#y').val(c.y);
$('#w').val(c.w);
$('#h').val(c.h);
$('#btnCrop').show();
};
</script>
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<form method="POST" action="upload" enctype="multipart/form-data">
Please select a file to upload :
<input type="file" name="file" class="file" id="imgInp" />
<div class="cropArea">
<img id="blah" src="#" alt="your image" />
</div>
<input type="hidden" id="x" name="x" />
<input type="hidden" id="y" name="y" />
<input type="hidden" id="w" name="w" />
<input type="hidden" id="h" name="h" />
<canvas id="canvas" height="5" width="5"></canvas>
</form>
<input type="button" id="btnCrop" value="Crop" style="display: none" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
You are missing this param
enctype: 'multipart/form-data'
$.ajax({
url: 'upload',
data: data,
contentType: false,
processData: false,
enctype: 'multipart/form-data',
type: 'POST',
success: function(data){
alert(data);
}
});
You should have this
var data = new FormData();
data.append('file', jQuery('#imgInp')[0].files[0]);
instead of
jQuery.each(jQuery('#imgInp')[0].files, function(i,file) {
data.append('file-'+i, file);
});
Later Edit 2: in your function dataURItoBlob(dataURI) add callback like this:
function dataURItoBlob(dataURI, callback) {
...
callback();
}
then in
$('#btnCrop').click(function () { ...
data.append('file', dataURItoBlob(canvas.toDataURL("image/jpeg", function(){
$.ajax({
url: 'upload',
data: data,
contentType: false,
processData: false,
type: 'POST',
success: function(data){
alert(data);
}
});
})));
this way, you are sure that you make the ajax call after dataURItoBlob is executed.