4

I've web app running. And it uses ajax upload. The issue is recently users are uploading too big images. So it's taking a bit more time. Users are complaining about that. So what I was thinking is this, 'If I somehow crop and resize the image via js and then send it to the server via ajax upload then the time will be reduced'. So is there any way to do that? Any idea for it?

Mazhar Ahmed
  • 1,523
  • 2
  • 24
  • 41
  • 1
    Why don't you just put a limit on filesize and dimensions? – elclanrs Jul 06 '13 at 08:25
  • possible duplicate, even if quite old still holds in the point http://stackoverflow.com/questions/2434458/image-resizing-client-side-with-javascript-before-upload-to-the-server – DRC Jul 06 '13 at 08:26
  • 1
    Putting limit will force the user to modify it himself. But it will loose the site subscriptions. – Mazhar Ahmed Jul 06 '13 at 08:27

1 Answers1

15

A solution is to use modern ways like FileReader and Canvas (But this works only on the latest modern browsers).

http://caniuse.com/filereader

http://caniuse.com/canvas

In this example i show how to let the client resize an image before uploading by setting a max width & height mantaining aspect ratio.

In this example max widthHeight = 64; your final image is c.toDataURL();

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
var h=function(e){
 var fr=new FileReader();
 fr.onload=function(e){
  var img=new Image();
  img.onload=function(){
     var MAXWidthHeight=64;
   var r=MAXWidthHeight/Math.max(this.width,this.height),
   w=Math.round(this.width*r),
   h=Math.round(this.height*r),
   c=document.createElement("canvas");
   c.width=w;c.height=h;
   c.getContext("2d").drawImage(this,0,0,w,h);
   this.src=c.toDataURL();
   document.body.appendChild(this);
  }
  img.src=e.target.result;
 }
 fr.readAsDataURL(e.target.files[0]);
}
window.onload=function(){
 document.getElementById('f').addEventListener('change',h,false);
}
</script>
</head>
<body>
<input type="file" id="f">
</body>
</html>

In the canvas part of the code you can also add a cropping function.


Edit as asked in the comments

c.toDataURL();

is the image base64_string you can store it in a hidden input,append to a new FormData() or wherever you want.

on the server

$data=explode(',',$base64_string);
$image=base64_decode($data[1]);

write to file

$f=fopen($fileName,"wb");
fwrite($f,$image); 
fclose($f);

or

$gd=imagecreatefromstring($image);

you can also store the whole base64 image string in the database and always use that.

cocco
  • 16,442
  • 7
  • 62
  • 77
  • This code is appending an img tag inside DOM, as soon as we choose the file. How about uploading that image to server by a click of a button? I guess we need to get that image to a stream and upload that stream to the server? How to convert this stream on the server to create an image file, then? – ilter Dec 20 '13 at 10:36
  • I am a .net guy :) But thanks for the codes, I am sure someone will benefit from these ;) – ilter Dec 20 '13 at 15:47
  • 1
    use .net to decode base64, but first split/explode the string with a comma the second part is the data you want. – cocco Dec 20 '13 at 16:10