1

I haven't found any solution to this particular problem, despite many similar questions. I have a number of folders, each containing a number of image files. I'd like to do a batch face detection on these files and send the face coordinates and other relevant data to a database, and I intend to use this jQuery plugin: http://facedetection.jaysalvat.com/. It works on one image at a time and returns all necessary data through this basic call:

var coords = $('img').faceDetection({
    complete:function(img,coords) {
      // Do stuff ...
    }
});

What I would like to do is to start from a list of all images, send one at a time to that function, make an AJAX call to a PHP file that puts the relevant data in a database, and after the AJAX business is finished send the next image to the face detection plugin ... until all images have been processed.

The best I've come up with so far is the following:

var tot = imgs.length;
facedetect(0);
function facedetect(imgn) {
    $('img').attr('src',imgs[imgn].path);
    $('img[src="' + imgs[imgn].path + '"]').load(function() {
        var coords = $('img').faceDetection({
            complete:function(img,coords) {
                // Create var json ...
                $.ajax({
                    type: "POST",
                    url: "test.php",
                    data: { data : json },
                    success: function() {
                        imgn++;
                        if(tot > imgn) {
                            facedetect(imgn);
                            return;
                        }
                    }, dataType: "json"
                });
            }
        });
    });
}

However, if I run this with a simple list of three images (imgs[0]-imgs[2]) I get one AJAX call for the first image, two for the second and four for the third instead of one for each. Obviously something is very wrong, but I can't figure out what, so any help would be appreciated.

Edit: I tried both a for loop and $().each() first, but since they don't wait for each image to load I tried going recursive instead. For that's what I intended to do – load one image at a time. The imgs.length is based on a PHP array and there was only one img tag in the document. However, your replies made me realize that I could in fact make sure all images are loaded before I even start the loop. I didn't even consider that, probably because I have several thousands of images, but I could do a few folders at a time, of course. So thanks, that's what I will try next. :) (But just for the sake of it, it would be interesting to find a working solution for the load one image at a time scenario as well.)

linurb
  • 307
  • 1
  • 4
  • 14
  • I would use `$('img').each(function(){ ... (this.src is the src) ... })` and not have the `imgn++; .. facedetect` within it which should avoid the problem of calling it more than once per image. – Popnoodles Jan 07 '14 at 20:58
  • Performing multiple parallel ajax requests with jQuery: http://stackoverflow.com/questions/1060539/parallel-asynchronous-ajax-requests-using-jquery – brandonscript Jan 07 '14 at 21:10

1 Answers1

0

Instead of sending your ajax queries recursively, try sending them in a for loop:

Edit: you may want to make the queries async = false if you do this so that the image src doesn't change and the next query doesn't fire before this one completes.

var tot = imgs.length;
for(var imgn=0; imgn<tot; imgn++)
{
  $('img').attr('src',imgs[imgn].path);
  $('img[src="' + imgs[imgn].path + '"]').load(function() {

     var coords = $('img').faceDetection({

        complete:function(img,coords) {

           $.ajax({
               dataType: "json",
               type: "POST",
               url: "test.php",
               data: { data : json },
               async: false,
               success: function(data) {console.log(data);},
               error: function(e){console.log(e.responseText);}
            });
        }
    });
}
kjh
  • 3,407
  • 8
  • 42
  • 79