I recently downloaded an open source webcam to gif script and when the gif is created it saves as a dataurl. Is their a way I can change this? I would rather it save in a folder on the server and be something like http://example.com/folder/image.gif
Code:
*global GIFEncoder,encode64*/
var encoder = new GIFEncoder(),
video = document.querySelector('video'),
canvas = document.querySelector('canvas'),
ctx = canvas.getContext('2d'),
localMediaStream = null,
snapshotPause = 0,
recording = true,
framesPause = 120,
maxFrames = 28,
totalFrames = 0,
t;
encoder.setSize(320, 240);
encoder.setRepeat(0);
encoder.setDelay(framesPause);
encoder.setQuality(90);
window.URL = window.URL || window.webkitURL;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
if (navigator.getUserMedia) {
navigator.getUserMedia({
audio: true,
video: true
}, function (stream) {
$('#start-image, #start-fake').hide();
$('#video, #start').show();
video.src = window.URL.createObjectURL(stream);
localMediaStream = stream;
}, function (e) {
console.log('Error:', e);
}
);
} else {
console.log('not supported');
}
function snapshot() {
if (localMediaStream) {
ctx.drawImage(video, 0, 0, 320, 240);
encoder.addFrame(ctx);
var image = $('<img />').attr('src', canvas.toDataURL('image/gif'));
$('#thumbs').append(image);
totalFrames++;
if (totalFrames === maxFrames) {
recordingEnd();
}
}
}
function recordingEnd() {
var binaryGif = encoder.stream().getData(),
dataUrl = 'data:image/gif;base64,' + encode64(binaryGif),
gif = $('<img />').attr('src', dataUrl);
totalFrames = 0;
recording = !recording;
$('#start').html('Start');
clearInterval(t);
$('#indicator').hide();
encoder.finish();
$('#result-gif').html('').append(gif);
overlayShow('preview');
//b64 = encode64(binaryGif);
}
function overlayShow(panel) {
$('.panel').hide();
$('#' + panel).show();
$('#overlay-bg').show();
$('#overlay').show();
}
function overlayHide() {
$('#overlay-bg').hide();
$('#overlay').hide();
}
$('#start').click(function () {
if (recording) {
recording = !recording;
$('#thumbs-holder-close').show();
$('#thumbs-holder').animate({
'margin-left': '320px'
}, 300);
$('#thumbs').html('');
encoder.start();
$('#indicator').show().animate({
width: '100%'
}, snapshotPause, function () {
$('#indicator').css({
'width': '0'
});
});
t = setInterval(function () {
snapshot();
$('#indicator').animate({
width: '100%'
}, snapshotPause, function () {
$('#indicator').css({
'width': '0'
});
});
}, snapshotPause);
$(this).html('Stop');
} else {
recordingEnd();
}
});
$('#thumbs-holder-close').click(function () {
$(this).hide();
$('#thumbs-holder').animate({
'margin-left': 0
}, 300);
});
$('#overlay-close').click(function () {
overlayHide();
});
$('.new').click(function () {
overlayHide();
});
$('#showSettings').click(function () {
overlayShow('settings');
});
$('input[type=range]').change(function () {
var id = $(this).attr('id'),
val = $(this).val();
$(this).next().html(val);
window[id] = parseInt(val);
if (id === 'framesPause') {
framesPause = val;
encoder.setDelay(framesPause);
}
});
$('#save').click(function () {
$.ajax({
url: 'images/save.php',
method: 'POST',
data: {
image: b64
},
dataType: 'json',
success: function(data) {
var a = $('<a />').attr('href', "images/" + data.name).html('permalink');
$('#url').append(a);
},
error: function(err) {
console.log(err);
}
});
});
##Convert your dataUrl into Blobs
function dataURLtoBlob(dataURL) {
// Decode the dataURL
var binary = atob(dataURL.split(',')[1]);
// Create 8-bit unsigned array
var array = [];
for(var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
// Return our Blob object
return new Blob([new Uint8Array(array)], {type: 'image/gif'});
}
/* var file= dataURLtoBlob(dataURL); */
Now, you can add the Blob as FormData and send to server
Sending data as Blob instead of dataUrl.
As bergi pointed out, the encode.stream().getData() actually returns a binary string.
var array = [];
for(var i = 0; i < binaryGIF.length; i++) {
array.push(binaryGIF.charCodeAt(i));
}
// Return our Blob object
var file = new Blob([new Uint8Array(array)], {type: 'image/gif'});
// Create new form data
var fd = new FormData();
// Append our Canvas image file to the form data
fd.append("sample-image-name-for-name-attribute", file);
// And send it
$.ajax({
url: "my-rest-endpoint",
type: "POST",
data: fd,
processData: false,
contentType: false,
}).done(function(respond){
alert(respond);
});
Hope it helps. You should be able to use the file on the server as you handle a normal file upload.
Related
I'm trying to save the base64 image code of a video snapshot...
To do that, I have a first function I found which builds the snapshot I want, this function, videoSnap, is asynchronous, and I'd like to send it through an ajax function for further actions.
Problem is that the result of my videoSnap is completed way after the ajax call, thus, anytime I'm trying to send the result as a parameter of the ajax function, the result stay undefined...
How can I do this to work? I thought about promise function with then() but still the same result... I keep getting the base64 code after the ajax call making it uneffective...
I'm starting to be short of solution and idea... ^^'
Thanks much in advance for your great help! :)
getTime = function (){
var t = new Date();
return t.getTime();
}
dump = function (r) {
var pre = document.createElement('pre');
pre.innerHTML = r;
document.body.appendChild(pre)
}
videoSnap = function (file){
var reader = new FileReader();
if (file.type.match('video')) {
reader.onload = function() {
var blob = new Blob([reader.result], {type: file.type});
var url = URL.createObjectURL(blob);
var video = document.createElement('video');
var timeupdate = function() {
var snap = snapImage();
if (snap.success) {
video.removeEventListener('timeupdate', timeupdate);
video.pause();
dump(getTime()+' : '+snap.image);
return snap.image;
}else{
return false;
}
};
video.addEventListener('loadeddata', function() {
var snap = snapImage();
if (snap.success) {
video.removeEventListener('timeupdate', timeupdate);
dump(getTime()+' : '+snap.image);
return snap.image;
}else{
return false;
}
});
var snapImage = function() {
var canvas = document.createElement('canvas');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
var image = canvas.toDataURL();
var success = image.length > 100000;
var result = { success: success, image: image };
return result;
};
video.addEventListener('timeupdate', timeupdate);
video.preload = 'metadata';
video.src = url;
// Load video in Safari / IE11
video.muted = true;
video.playsInline = true;
video.play();
};
reader.readAsArrayBuffer(file);
}else{
return false;
}
}
dump(getTime());
var base64Img = videoSnap(videoFile);
formData.append("videoSnap",base64Img);
/*
function videoSnapPromise(vid) {
return new Promise((resolve) => {
resolve(videoSnap(vid));
})
}
function appendResolve(resolve) {
formData.append("videoSnap",resolve);
}
const promise = videoSnap(videoFile);
promise.then(appendResolve);
*/
dump(getTime());
$.ajax({
type: 'POST',
url: 'uploadBase64Img.php',
timeout: 10000,
data: formData,
processData: false,
contentType: false,
dataType: "json",
complete: function() {
// complete function
}
});
dump(getTime());
One way to do this would be to create a callback function and send it to the first function as a parameter, then refactor your first function to call that callback and pass it the result of the operation instead of returning it.
something like this should work:
getTime = function() {
var t = new Date();
return t.getTime();
}
dump = function(r) {
var pre = document.createElement('pre');
pre.innerHTML = r;
document.body.appendChild(pre)
}
var videoSnap = function(file, callback) {
var reader = new FileReader();
if (file.type.match('video')) {
reader.onload = function() {
var blob = new Blob([reader.result], {
type: file.type
});
var url = URL.createObjectURL(blob);
var video = document.createElement('video');
var timeupdate = function() {
var snap = snapImage();
if (snap.success) {
video.removeEventListener('timeupdate', timeupdate);
video.pause();
dump(getTime() + ' : ' + snap.image);
callback(snap.image);
} else {
callback(false);
}
};
video.addEventListener('loadeddata', function() {
var snap = snapImage();
if (snap.success) {
video.removeEventListener('timeupdate', timeupdate);
dump(getTime() + ' : ' + snap.image);
callback(snap.image);
} else {
callback(false);
}
});
var snapImage = function() {
var canvas = document.createElement('canvas');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
var image = canvas.toDataURL();
var success = image.length > 100000;
var result = {
success: success,
image: image
};
callback(result);
};
video.addEventListener('timeupdate', timeupdate);
video.preload = 'metadata';
video.src = url;
// Load video in Safari / IE11
video.muted = true;
video.playsInline = true;
video.play();
};
reader.readAsArrayBuffer(file);
} else {
callback(false);
}
}
var doAjax = function(base64Img) {
var formData = FormData();
formData.append("videoSnap", base64Img);
$.ajax({
type: 'POST',
url: 'uploadBase64Img.php',
timeout: 10000,
data: formData,
processData: false,
contentType: false,
dataType: "json",
complete: function() {
// complete function
}
});
}
videoSnap(videoFile, doAjax);
My project is about saving the cropped image and show it in the view.
in my form when i cropped the image it works, but when i want to change the image so i crop it again and save. it create two rows with same image.
and when i change the image 3 times it create 3 rows with the same image and so on.
there is method called replace() that i have to use but i dont know how to use it.
this is my code
window.addEventListener('DOMContentLoaded', function () {
var avatar = document.getElementById('avatar');
var image = document.getElementById('image');
var input = document.getElementById('input');
var $progress = $('.progress');
var $progressBar = $('.progress-bar');
var $alert = $('.alert');
var $modal = $('#modal');
var cropper;
var title = $('#title');
var description = $('#description');
var arabic_title = $('#arabic_title');
var arabic_description = $('#arabic_description');
$('[data-toggle="tooltip"]').tooltip();
input.addEventListener('change', function (e) {
var files = e.target.files;
var done = function (url) {
input.value = '';
image.src = url;
// $alert.hide();
$modal.modal('show');
};
var reader;
var file;
var url;
if (files && files.length > 0) {
file = files[0];
if (FileReader) {
reader = new FileReader();
reader.onload = function (e) {
done(reader.result);
console.log('ok2');
};
reader.readAsDataURL(file);
console.log('ok3');
}
}
});
$modal.on('shown.bs.modal', function () {
cropper = new Cropper(image, {
aspectRatio: 1.7,
viewMode: 3,
});
}).on('hidden.bs.modal', function () {
cropper.destroy();
cropper = null;
});
document.getElementById('crop').addEventListener('click', function () {
var initialAvatarURL;
var canvas;
$modal.modal('hide');
if (cropper) {
canvas = cropper.getCroppedCanvas({
width: 400,
height: 400,
});
initialAvatarURL = avatar.src;
avatar.src = canvas.toDataURL();
$progress.show();
$alert.removeClass('alert-success alert-warning');
document.getElementById('save').addEventListener('click', function () {
canvas.toBlob(function (blob) {
var formData = new FormData();
formData.append('avatar', blob);
formData.append('title', title.val());
formData.append('description', description.val());
formData.append('arabic_title', arabic_title.val());
formData.append('arabic_description', arabic_description.val());
if (title.val() !== '' && description.val() !== '' && arabic_title.val() !== '' && arabic_description.val() !== '') {
for (let pair of formData.entries()) {
console.log(pair[0] + ', ' + pair[1]);
}
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax("{{url('admin/services')}}", {
method: 'POST',
data: formData,
processData: false,
contentType: false,
xhr: function () {
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function (e) {
var percent = '0';
var percentage = '0%';
if (e.lengthComputable) {
percent = Math.round((e.loaded / e.total) * 100);
percentage = percent + '%';
$progressBar.width(percentage).attr('aria-valuenow', percent).text(percentage);
}
};
return xhr;
},
success: function (data) {
$alert.show().addClass('alert-success').text('Upload success');
console.log(data);
},
error: function (error) {
avatar.src = initialAvatarURL;
$alert.show().addClass('alert-warning').text('Upload error');
console.log(error);
},
complete: function () {
$progress.hide();
},
});
}
});
});
}
});
});
$service = 'No service';
if (isset($_FILES['img'])) {
$service = Service::create(['title'=>$request->title,
'description'=>$request->description,
'photo'=>$request->img]);
}
return $service;
Try this.
Your Form Should Be
<form action="files/upload" method="post" enctype="multipart/form-data">
<input type="file" name="photo"/>
</form
Your Controller Should Be like
if ($request->hasFile('photo')) {
// move file upload here
}
I am trying to record my screen using media Recorder API using electron like this. I have a start function which starts recording the screen. I use the electron API for this. and a stop function to stop recording using MediaRecorder API from - https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder.
Currently it stops after 7 seconds.
This is how it looks like.
var electron = require('electron');
var SECRET_KEY = 'test.html';
var recorder;
var blobs = [];
console.log("its loading");
function startRecording() {
var title = document.title;
document.title = SECRET_KEY;
console.log("Started Recording");
electron.desktopCapturer.getSources({ types: ['window', 'screen'] }, function(error, sources) {
if (error) throw error;
for (let i = 0; i < sources.length; i++) {
let src = sources[i];
if (src.name === SECRET_KEY) {
console.log("its passing");
document.title = title;
navigator.webkitGetUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: src.id,
minWidth: 800,
maxWidth: 1280,
minHeight: 600,
maxHeight: 720
}
}
}, handleStream, handleUserMediaError);
return;
}
}
});
}
function handleStream(stream) {
recorder = new MediaRecorder(stream);
blobs = [];
recorder.ondataavailable = function(event) {
blobs.push(event.data);
};
recorder.start();
}
function stopRecording() {
recorder.stop();
toArrayBuffer(new Blob(blobs, { type: "video/webm" }), function(ab) {
var buffer = toBuffer(ab);
var file = `./SavedVideos/example.webm`;
fs.writeFile(file, buffer, function(err) {
if (err) {
console.error('Failed to save video ' + err);
} else {
console.log('Saved video: ' + file);
}
});
});
}
function handleUserMediaError(e) {
console.error('handleUserMediaError', e);
}
function toArrayBuffer(blob, cb) {
let fileReader = new FileReader();
fileReader.onload = function() {
let arrayBuffer = this.result;
cb(arrayBuffer);
};
fileReader.readAsArrayBuffer(blob);
}
function toBuffer(ab) {
let buffer = new Buffer(ab.byteLength);
let arr = new Uint8Array(ab);
for (let i = 0; i < arr.byteLength; i++) {
buffer[i] = arr[i];
}
return buffer;
}
var startbutton = document.getElementById('start');
var stopbutton = document.getElementById('stop');
// startbutton.onclick = startRecording();
// stopbutton.onclick = stopRecording();
// Record for 7 seconds and save to disk
startRecording();
setTimeout(function() { stopRecording() }, 7000);
The code is passing without any error. But when I open the video which is saved using VLC, it has 0 bytes and it doesn't start.
How can fix this ?
You didn't wait for value to come in stopReocoring. You need to change your stopRecording function to following:
function stopRecording() {
var save = function() {
console.log(blobs);
toArrayBuffer(new Blob(blobs, {type: 'video/webm'}), function(ab) {
console.log(ab);
var buffer = toBuffer(ab);
var file = `./videos/example.webm`;
fs.writeFile(file, buffer, function(err) {
if (err) {
console.error('Failed to save video ' + err);
} else {
console.log('Saved video: ' + file);
}
});
});
};
recorder.onstop = save;
recorder.stop();
}
Trying to overcome the variable deficiencies of Flash's upload-to-server function - particularly not being able to track upload progress when cookies are required - I have decided to create a JavaScript function that does the upload and keeps track of the upload progress events.
Here it is:
window.you_animate = {
objToString: function(obj) {
var res = "{";
for (var str in obj) {
res += str +"=" + obj[str] + ",";
}
res += "}";
return res;
},
upload: function(url, _files, _data, progressCb, successCb, errorCb) {
alert("a,"+url);
var fd = new FormData(),
files = _files || [],
data = _data || [],
i;
alert("b");
for (i in data) {
fd.append(i, data[i]);
}
alert("c");
for (i = 0; i < files.length; i++) {
var file = files[i];
alert(i+"/"+files.length+" file= "+you_animate.objToString(file));
var blob = file.file || new Blob(file.data, {
type: file.type
});
alert("blob= "+you_animate.objToString(blob));
fd.append(file.name, blob);
}
alert("d");
var ajax_opts = {
type: 'POST',
url: url,
data: fd,
headers: {},
dataType: 'json',
contentType: false,
processData: false,
xhr: function() {
alert("1");
var xhr = new window.XMLHttpRequest();
if (xhr.upload) {
xhr.upload.addEventListener('progress', progressCb, false);
}
return xhr;
},
success: successCb || $.noop,
error: errorCb || $.noop
};
alert("2");
$.ajax(ajax_opts);
alert("3");
},
uploadProgress: {},
// => _data = base64 binary
uploadFromFlash: function(url, _files, _data) {
alert("0");
var uploadProcess = {};
var uploadProcessID = "id" + Math.floor(Math.random() * 1000000).toString();
you_animate.uploadProgress[uploadProcessID] = uploadProcess;
// workaround for Flash bug ("[]" in variable name)
for (var str in _data) {
_data["UploadCharacterForm["+str+"]"] = _data[str];
delete _data[str];
}
alert("01");
// base64 -> Blob-friendly stuff
for (i = 0; i < _files.length; i++) {
var file = _files[i];
var binary = atob(file.data);
var array = new Uint8Array(binary.length);
for( var i = 0; i < binary.length; ++i ) { array[i] = binary.charCodeAt(i) }
file.data = [array]; // NOTE : why "[array]" and not "array" ??
}
alert("02");
you_animate.upload(url, _files, _data,
function(progressEvent) {
uploadProcess.progressEvent = progressEvent;
},
function(successEvent) {
uploadProcess.successEvent = successEvent;
uploadProcess = null;
},
function(errorEvent) {
uploadProcess.errorEvent = errorEvent;
uploadProcess = null;
}
);
return uploadProcessID;
},
trackProcessID: function(id) {
return you_animate.uploadProgress[id];
},
destroyProcessID: function(id) {
delete you_animate.uploadProgress[id];
},
uploadForm: function(form, progressCb, successCb, errorCb) {
var $form = $(form),
action = $form.attr('action') + '?json';
var data = $form.serializeArray().reduce(function(prev, curr){
prev[curr.name] = curr.value; return prev;
}, {} );
var $files = $form.find('input[type=file]');
var files = [];
$files.each(function(index, node) {
if (node.files[0]) {
files.push({
name: node.name,
file: node.files[0]
});
}
});
you_animate.upload(action, files, data, progressCb, successCb, errorCb);
}
};
Question 1: the progress event differs between Chrome and Firefox. The first returns loaded & totalSize (among lots of other stuff), while Firefox returns loaded & total!!!
Is there somewhere a specification for the returned progress event?!
Question 2: Internet Explorer 8 crashes right after alert("0") ! Maybe it doesn't like "[ ]" in the following line:
_data["UploadCharacterForm["+str+"]"] = _data[str];
Anything to do about that?
Below is the code I am using which basically passes multiple files to be uploaded. In the loop each file is resized client side and then uploaded.
I want to execute an ajax call after the loop is finished uploading the photos. The ajax call basically reloads a specific div and refreshes the photos.
How do I prevent the ajax call from executing until the loop has finished.
if (window.File && window.FileReader && window.FileList && window.Blob)
{
var files = document.getElementById('filesToUpload').files;
for(var i = 0; i < files.length; i++)
{
resizeAndUpload(files[i]);
}
// when loop finished, execute ajax call
$.ajax
({
type: "POST",
url: "photos.php",
data: dataString,
success: function(html)
{
$("#photo-body").html(html);
}
});
}
}
function resizeAndUpload(file)
{
var reader = new FileReader();
reader.onloadend = function()
{
var tempImg = new Image();
tempImg.src = reader.result;
tempImg.onload = function()
{
var MAX_WIDTH = 382.25;
var MAX_HEIGHT = 258.5;
var tempW = tempImg.width;
var tempH = tempImg.height;
if (tempW > tempH)
{
if (tempW > MAX_WIDTH)
{
tempH *= MAX_WIDTH / tempW;
tempW = MAX_WIDTH;
}
}
else
{
if (tempH > MAX_HEIGHT)
{
tempW *= MAX_HEIGHT / tempH;
tempH = MAX_HEIGHT;
}
}
var canvas = document.createElement('canvas');
canvas.width = tempW;
canvas.height = tempH;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0, tempW, tempH);
var dataURL = canvas.toDataURL("image/jpeg");
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(ev)
{
document.getElementById('filesInfo').innerHTML = 'Upload Complete';
};
xhr.open('POST', 'upload-resized-photos.php', true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
var data = 'image=' + dataURL;
xhr.send(data);
}
}
reader.readAsDataURL(file);
}
var _validFileExtensions = [".jpg", ".jpeg", ".bmp", ".gif", ".png"];
function Validate(oForm)
{
var arrInputs = oForm.getElementsByTagName("input");
for (var i = 0; i < arrInputs.length; i++)
{
var oInput = arrInputs[i];
if (oInput.type == "file")
{
var sFileName = oInput.value;
if (sFileName.length > 0)
{
var blnValid = false;
for (var j = 0; j < _validFileExtensions.length; j++)
{
var sCurExtension = _validFileExtensions[j];
if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase())
{
blnValid = true;
break;
}
}
if (!blnValid)
{
alert("Sorry, " + sFileName + " is invalid, allowed extensions are: " + _validFileExtensions.join(", "));
return false;
}
}
}
}
return true;
}
You can wrap the $ajax call in a function, and call the function at the end of the final loop.
(just the top part of your script)
if (window.File && window.FileReader && window.FileList && window.Blob) {
function loopFinished(){
$.ajax
({
type: "POST",
url: "photos.php",
data: dataString,
success: function(html)
{
$("#photo-body").html(html);
}
});
}
var files = document.getElementById('filesToUpload').files;
for(var i = 0; i < files.length; i++)
{
resizeAndUpload(files[i]);
if (files.length+1 == [i]){
loopFinished();
}
}
}
You can use any promise library to do this. Here is example of using jQuery promise
(function ($) {
var files = [1, 2, 3, 4],
allPromises = [];
for (var i = 0; i < files.length; i++) {
var promise = resizeAndUpload(files[i]);
allPromises.push(promise);
}
$.when.apply($, allPromises).done(function () {
makeAjaxCall();
});
function makeAjaxCall() {
console.log('Put Ajax call here');
}
function resizeAndUpload(file) {
var defer = $.Deferred();
//Set timeout simulates your long running process of processing file
setTimeout(function () {
console.log('processing file ' + file);
defer.resolve();
}, 2000);
return defer.promise();
}
})(jQuery);
Here is a jSFiddle http://jsfiddle.net/x6oh471f/2/
One or more of the methods in your resizeAndUpload() function must be happening asynchronously. Which means they'll do their thing in the background while the rest of your javascript is run and they should fire an event when they are complete. You will want to call the ajax method once the last one of these methods has complete and event fired. For example, the fileReader methods are asychronous. Which means you will probably need to do something like:
FileReader.onloadend = function(){
totalFilesLoaded = totalFilesLoaded + 1;
if (totalFilesLoaded == files.length){
//all files have been uploaded, run $ajax
}
}
EDIT: now you have uploaded the rest of your code, try something like this:
window.totalFilesLoaded = 0;
var files = document.getElementById('filesToUpload').files;
window.totalFilesToLoad = files;
if (window.File && window.FileReader && window.FileList && window.Blob)
{
for(var i = 0; i < files.length; i++)
{
resizeAndUpload(files[i]);
}
}
Separate ajax function:
window.runAjax = function(){
$.ajax
({
type: "POST",
url: "photos.php",
data: dataString,
success: function(html)
{
$("#photo-body").html(html);
}
});
}
function resizeAndUpload(file)
{
var reader = new FileReader();
reader.onloadend = function()
{
...
xhr.onreadystatechange = function(ev)
{
document.getElementById('filesInfo').innerHTML = 'Upload Complete';
window.totalFilesLoaded++;
if (window.totalFilesLoaded == window.totalFilesToLoad.length){
window.runAjax()
}
};
...
}
reader.readAsDataURL(file);
}