Image resize before upload
Asked Answered
A

9

52

I need to provide a means for a user to upload photos to their web site in jpeg format. However, the photos are very large in original size, and I would like to make the resize before upload option very effortless for the user. It seems my only options are a client side application that resizes the photos before uploading them via a web service, or a client side JavaScript hook on the upload operation that resizes the images. The second option is very tentative because I don't have a JavaScript image resizing library, and it will be difficult to get the JavaScript to run my current resize tool, ImageMagick.

I'm sure this is not too uncommon a scenario, and some suggestions or pointers to sites that do this will be appreciated.

Aloke answered 7/6, 2009 at 13:49 Comment(0)
E
7

You have several options:

  1. Java
  2. ActiveX (only on windows)
  3. Silverlight
  4. Flash
  5. Flex
  6. Google Gears (the most recent version is capable of resizing and drag and drop from your desktop)

I've done a lot of research looking for a similar solution to what you have described and there a lot of solutions out there that vary a lot in quality and flexibility.

My suggestion is find a solution which will do 80% of what you need and customize it to suit your needs.

Ethaethan answered 9/6, 2009 at 4:1 Comment(3)
Yes, my suggestion of google gears was made prior to the removal (note the date of my answer).Ethaethan
@Ethaethan any change 5 years after ?Swampy
As of 2011, it can be done natively. See the answer below: https://mcmap.net/q/282232/-image-resize-before-uploadPolytonality
S
61

In 2011, we can know do it with the File API, and canvas. This works for now only in firefox and chrome. Here is an example :

var file = YOUR_FILE,
    fileType = file.type,
    reader = new FileReader();

reader.onloadend = function() {
  var image = new Image();
      image.src = reader.result;

  image.onload = function() {
    var maxWidth = 960,
        maxHeight = 960,
        imageWidth = image.width,
        imageHeight = image.height;

    if (imageWidth > imageHeight) {
      if (imageWidth > maxWidth) {
        imageHeight *= maxWidth / imageWidth;
        imageWidth = maxWidth;
      }
    }
    else {
      if (imageHeight > maxHeight) {
        imageWidth *= maxHeight / imageHeight;
        imageHeight = maxHeight;
      }
    }

    var canvas = document.createElement('canvas');
    canvas.width = imageWidth;
    canvas.height = imageHeight;

    var ctx = canvas.getContext("2d");
    ctx.drawImage(this, 0, 0, imageWidth, imageHeight);

    // The resized file ready for upload
    var finalFile = canvas.toDataURL(fileType);
  }
}

reader.readAsDataURL(file);
Su answered 6/12, 2011 at 9:39 Comment(4)
how would you make a proper ajax post request with the file appearing as it would with a regular form? I want to make the change transparent to the rest of my application.Orthostichy
I've write a blog post (in french) about it. Here is it translated by google: translate.google.fr/…Su
I know this is a bit old, but should the 5th line from the bottom be var file = canvas.toDataURL(fileType); ? Otherwise, finalFile is just kinda set and forgotten.Whiplash
Well once you've got your finalFile you should upload it (by passing finalFile to an upload function). This part is not shown there since the question was about how to resize an image.Su
M
12

There is multiple-technology-capable Plupload tool which declares that it can do resizing before upload, but I haven't tried it yet. I have also find a suitable answer in my question about binary image handling javascript libs.

Menado answered 3/3, 2010 at 8:2 Comment(0)
E
7

You have several options:

  1. Java
  2. ActiveX (only on windows)
  3. Silverlight
  4. Flash
  5. Flex
  6. Google Gears (the most recent version is capable of resizing and drag and drop from your desktop)

I've done a lot of research looking for a similar solution to what you have described and there a lot of solutions out there that vary a lot in quality and flexibility.

My suggestion is find a solution which will do 80% of what you need and customize it to suit your needs.

Ethaethan answered 9/6, 2009 at 4:1 Comment(3)
Yes, my suggestion of google gears was made prior to the removal (note the date of my answer).Ethaethan
@Ethaethan any change 5 years after ?Swampy
As of 2011, it can be done natively. See the answer below: https://mcmap.net/q/282232/-image-resize-before-uploadPolytonality
S
2

I think you need Java or ActiveX for that. For example Thin Image Upload

Servais answered 7/6, 2009 at 13:53 Comment(0)
I
2

What jao and russau say is true. The reason being is JavaScript does not have access to the local filesystem due to security reasons. If JavaScript could "see" your image files, it could see any file, and that is dangerous.

You need an application-level control to be able to do this, and that means Flash, Java or Active-X.

Irretentive answered 7/6, 2009 at 15:55 Comment(0)
P
2

Here some modifications to feed tensorflow.js(soo fast with it!!) with resized and cropped image (256x256px), plus showing original image under cropped image, to see what is cut off.

$("#image-selector").change(function(){


var file = $("#image-selector").prop('files')[0];   

var maxSize = 256;  // well now its minsize
var reader = new FileReader();
var image = new Image();
var canvas = document.createElement('canvas');
var canvas2 = document.createElement('canvas');     

var dataURItoBlob = function (dataURI) {
    var bytes = dataURI.split(',')[0].indexOf('base64') >= 0 ?
        atob(dataURI.split(',')[1]) :
        unescape(dataURI.split(',')[1]);
    var mime = dataURI.split(',')[0].split(':')[1].split(';')[0];
    var max = bytes.length;
    var ia = new Uint8Array(max);
    for (var i = 0; i < max; i++)
        ia[i] = bytes.charCodeAt(i);
    return new Blob([ia], { type: mime });
};

var resize = function () {
    var width = image.width;
    var height = image.height; 

    if (width > height) {           
        if (width > maxSize) { 
            width *= maxSize / height; 
            height = maxSize;
        }
    } else {
        if (height > maxSize) {
            height *= maxSize / width;
            width = maxSize;
        }           
    }
    if (width==height) { width = 256; height = 256; }


    var posiw = 0;
    var posih = 0;
    if (width > height) {posiw = (width-height)/2; }
    if (height > width) {posih = ((height - width) / 2);} 
    canvas.width = 256;
    canvas.height = 256;
    canvas2.width = width;
    canvas2.height = height;        
     console.log('iw:'+image.width+' ih:'+image.height+' w:'+width+' h:'+height+' posiw:'+posiw+' posih:'+posih);
    canvas.getContext('2d').drawImage(image, (-1)*posiw, (-1)*posih, width, height); 
    canvas2.getContext('2d').drawImage(image, 0, 0, width, height); 
    var dataUrl = canvas.toDataURL('image/jpeg');
    var dataUrl2 = canvas2.toDataURL('image/jpeg');     

        if ($("#selected-image").attr("src")) {
            $("#imgspeicher").append('<div style="width:100%; border-radius: 5px; background-color: #eee; margin-top:10px;"><div style="position: relative; margin:10px auto;"><img id="selected-image6" src="'+$("#selected-image").attr("src")+'" style="margin: '+document.getElementById('selected-image').style.margin+';position: absolute; z-index: 999;" width="" height=""><img id="selected-image2" src="'+$("#selected-image2").attr("src")+'" style="margin: 10px; opacity: 0.4;"></div><div class="row" style="margin:10px auto; text-align: left;"> <ol>'+$("#prediction-list").html()+'</ol> </div></div>');
        }

    $("#selected-image").attr("src",dataUrl);
    $("#selected-image").width(256);
    $("#selected-image").height(256);
    $("#selected-image").css('margin-top',posih+10+'px');
    $("#selected-image").css('margin-left',posiw+10+'px');      
    $("#selected-image2").attr("src",dataUrl2); 
    $("#prediction-list").empty();
    console.log("Image was loaded, resized and cropped");
    return dataURItoBlob(dataUrl);



};

return new Promise(function (ok, no) {

    reader.onload = function (readerEvent) {
        image.onload = function () { return ok(resize()); };
        image.src = readerEvent.target.result;
    };

let file = $("#image-selector").prop('files')[0];       
reader.readAsDataURL(file);});}); 

Html implementation:

<input id ="image-selector" class="form-control border-0" type="file">

<div style="position: relative; margin:10px auto; width:100%;" id="imgnow">
 <img id="selected-image" src="" style="margin: 10px; position: absolute; z-index: 999;">
 <img id="selected-image2" src="" style="margin: 10px; opacity: 0.4;">                       
</div> 

Also not resize to a maximum width/height, but to minimum. We get a 256x256px square image.

Procyon answered 12/1, 2019 at 13:58 Comment(0)
F
1

Unfortunately you won't be able to resize the images in Javascript. It is possible in Silverlight 2 tho.

If you want to buy something already done: Aurigma Image Uploader is pretty impressive - $USD250 for the ActiveX and Java versions. There's some demos on the site, I'm pretty sure facebook use the same control.

Flying answered 7/6, 2009 at 14:2 Comment(0)
S
0

Pure JavaScript solution. My code resizes JPEG by bilinear interpolation, and it doesn't lose exif.

https://github.com/hMatoba/JavaScript-MinifyJpegAsync

function post(data) {
    var req = new XMLHttpRequest();
    req.open("POST", "/jpeg", false);
    req.setRequestHeader('Content-Type', 'image/jpeg');
    req.send(data.buffer);
}

function handleFileSelect(evt) {
    var files = evt.target.files;

    for (var i = 0, f; f = files[i]; i++){
        var reader = new FileReader();
        reader.onloadend = function(e){
            MinifyJpegAsync.minify(e.target.result, 1280, post);
        };
        reader.readAsDataURL(f);
    }
}

document.getElementById('files').addEventListener('change', handleFileSelect, false);
Surround answered 20/2, 2015 at 1:40 Comment(0)
C
0

You can resize the image in the client-side before uploading it using an image processing framework.

Below I used MarvinJ to create a runnable code based on the example in the following page: "Processing images in client-side before uploading it to a server"

Basically I use the method Marvin.scale(...) to resize the image. Then, I upload the image as a blob (using the method image.toBlob()). The server answers back providing a URL of the received image.

/***********************************************
 * GLOBAL VARS
 **********************************************/
var image = new MarvinImage();

/***********************************************
 * FILE CHOOSER AND UPLOAD
 **********************************************/
 $('#fileUpload').change(function (event) {
	form = new FormData();
	form.append('name', event.target.files[0].name);
	
	reader = new FileReader();
	reader.readAsDataURL(event.target.files[0]);
	
	reader.onload = function(){
		image.load(reader.result, imageLoaded);
	};
	
});

function resizeAndSendToServer(){
  $("#divServerResponse").html("uploading...");
	$.ajax({
		method: 'POST',
		url: 'https://www.marvinj.org/backoffice/imageUpload.php',
		data: form,
		enctype: 'multipart/form-data',
		contentType: false,
		processData: false,
		
	   
		success: function (resp) {
       $("#divServerResponse").html("SERVER RESPONSE (NEW IMAGE):<br/><img src='"+resp+"' style='max-width:400px'></img>");
		},
		error: function (data) {
			console.log("error:"+error);
			console.log(data);
		},
		
	});
};

/***********************************************
 * IMAGE MANIPULATION
 **********************************************/
function imageLoaded(){
  Marvin.scale(image.clone(), image, 120);
  form.append("blob", image.toBlob());
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.marvinj.org/releases/marvinj-0.8.js"></script>
<form id="form" action='/backoffice/imageUpload.php' style='margin:auto;' method='post' enctype='multipart/form-data'>
				<input type='file' id='fileUpload' class='upload' name='userfile'/>
</form><br/>
<button type="button" onclick="resizeAndSendToServer()">Resize and Send to Server</button><br/><br/>
<div id="divServerResponse">
</div>
Candlestand answered 28/5, 2018 at 21:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.