2

In my code I try to save 27 images into my downloads folder but when i run the code it only saves a maximum of 10 images into my downloads folder. I logged my results in the console and the code seems to be running correctly. Initially i thought Chrome or the online p5.js Web Editor had a problem with too many save requests being sent at the same time so i tried to put a few seconds of delay after each save but that approach didn't work. Is there a limit to how many downloads Chrome allows from a single site (maybe within a certain amount of time)?

I know the code is not efficient but speed is not important now as I am just testing something and the for loops are structured that way for a specific reason.

let t, w, img, mod, p, dim;

function preload() {
//image loaded
img = loadImage("rose.jpg");
}

function update(pos, a, b, c) {
  let i = img.pixels[pos + a];
  let j = img.pixels[pos + b];
  let k = img.pixels[pos + c];
  let l = img.pixels[pos + 3];
  return [i, j, k, l];
}

function setup() {
  // modified image created and its pixels loaded
 image(img, 0, 0, width, height);
  mod = createImage(img.width, img.height);
  img.loadPixels();
  mod.loadPixels();

  // 3 for loops make counter for image names
  for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
      for (let k = 0; k < 3; k++) {
        //loop through the pixels of the image
        for (let l = 0; l < mod.height * 4; l++) {
          //m is incremented by 4 so each set of rgba values can be manipulated by the update function
          for (let m = 0; m < mod.width; m += 4) {
            //pixel index is calculated and update returns an array of pixel values
            w = img.width * l + m;
            t = update(w, i, j, k);
            for (let n = 0; n < 4; n++) {
              mod.pixels[w + n] = t[n];
            }
          }
        }
        //canvas is created and image is displayed
        mod.updatePixels();
        dim = 550;
        createCanvas(dim, dim);
        image(mod, 0, 0, width, height);
        //save request
        save(mod, ("edited" + i + j + k + ".jpg"));
      }
    }
  }
}
PiwiTheKiwi
  • 129
  • 1
  • 14

3 Answers3

2

P5.js is open source. You can view the source code that downloads the files here in the p5.prototype.downloadFile function.

I don't see any restrictions around how many files can be downloaded, so my guess is it's either coming from the browser or from the library that p5.js uses to save the files. You might want to try out other browsers or see if there's a restriction in the file saving library.

For what it's worth, I tried this out using this simplified example:

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(220);
  ellipse(mouseX, mouseY, 20, 20);
  // save(frameCount + ".png");
}

function mouseClicked() {
  for(let i = 0; i < 100; i++) {
    save(i + ".png");
  }
}

If I click the mouse, then only 10 images are saved. Interestingly, they are not always the first 10, so there appears to be some kind of race happening between the save calls.

However, if I uncomment the call to save() that's inside the draw() function, then more than 10 are saved, but it seems like most of the images are skipped.

Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
  • That's interesting. Seems like a bug? There should be a buffer in place... A solution could be to create you own buffer and save images to there and then later save them. But then you would need a callback for when it is done saving, can't find any of those in the p5 functions. Then you could as well make your own downloader.. – Ethan Hermsey Apr 13 '20 at 01:33
  • It seems like Chrome has some sort of stack it uses when downloading files where only 10 files can be downloaded at a time but if more items are downloaded from other sites it will download the extra files as the current ones finish but p5 seems to "give up" after the first 10 files are added as downloads and leaves the rest – PiwiTheKiwi Jun 18 '20 at 15:26
0

A trick to avoid race cond. in this context is to pause execution for a few millisec.

example:

let sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms))

await sleep(300) after save(mod, ("edited" + i + j + k + ".jpg"));.

jcchuks
  • 881
  • 8
  • 16
0

Adding images to an array and then saving them worked for me:

let images = [];

function mouseClicked() {
  for (j = 0; j < n; j++) {
    for (i = 0; i < n; i++) {
      let c = get(i, j, w, h);
      images.push(c);
    }
  }
  for (let i = 0; i < images.length; i++) {
    images[i].save("image", "png");
  }
}
Joyboy
  • 1