Dynamic Image Array

Hello all

I am trying to create a slideshow program that accepts different images from time to time, and I want to adjust the array so that (a) it does not freeze while waiting for the images to load, and (b) it does not crash due to different array sizes.

The image array may receive for example 10 images now, and after a couple of minutes I want to delete these images, and use 15 different images. However, I want to keep my slideshow constant. What will I have to do to achieve this? An image buffer perhaps? I am not sure.

Here is a code example that generates random number of images. While running, pressing the 'a' key will get a new random size.

ImageSlide[] newSlides;

float[] randomTransition;
int randomMax;

void setup() {
  size(400, 400, P3D);
  frameRate(30);

  setupSlides();
}

void draw() {
  background(0);

  if (keyPressed) {
    if (key=='a') setupSlides();
  }

  for (int i=0; i<randomMax; i++) {
    newSlides[i].run();
  }
}

void setupSlides() {
  randomMax = (int) random (5, 10);

  newSlides = new ImageSlide[randomMax];
  randomTransition = new float[randomMax];

  for (int i=0; i<randomMax; i++) {
    //Random transition times for the ImageSlide class
    randomTransition[i] = random(0.002, 0.007);

    //Create the ImageSlide objects - Load new picture files
    newSlides[i] = new ImageSlide(randomTransition[i], i);
    newSlides[i].loadFile1();
    newSlides[i].loadFile2();
  }
}

class ImageSlide {
  float interpValue1 = 0;
  float percentage1, finalValue1;
  int slider1, counterTime1, counter1;
  int storedValue1 = 0;

  float interpValue2 = 0;
  float percentage2, finalValue2;
  int slider2, counterTime2, counter2;
  int storedValue2 = 0;  

  PImage imageOne, imageTwo;

  //Set variables for the counters
  float counting1 = 0.;
  boolean setCounter1 = true;
  float counting2 = 0.;
  boolean setCounter2 = false;

  float changeSpeed;

  int maxImages=0;

  ImageSlide (float tempSpeed, int maxImg) {
    changeSpeed = tempSpeed;
    maxImages = maxImg;
  }

  void loadFile1() {
    //Load a random file from the data folder
    int randImg1 = (int) random (maxImages);
    String imageFilename1;
    imageFilename1=str(randImg1) + ".jpg";
    imageOne=loadImage(imageFilename1);
    imageOne.resize(400, 400);
  }

  void loadFile2() {
    //Load a random file from the data folder
    int randImg2 = (int) random (maxImages);
    String imageFilename2;
    imageFilename2=str(randImg2) + ".jpg";
    imageTwo=loadImage(imageFilename2);
    imageTwo.resize(400, 400);
  }

  void interpolate1(int newValue1) {
    //Interpolate values - New value is the incoming value (either 0 or 255) 
    if (storedValue1 != newValue1) counterTime1 = 100;
    if (counterTime1 != 0) counter1++;
    if (counter1 > counterTime1) counter1 = counterTime1;
    percentage1 = map (counter1, 0, 100, 0., 1.);
    interpValue1 = lerp (storedValue1, newValue1, percentage1);
    if (percentage1 == 1.) storedValue1 = newValue1;
    counterTime1 = 0;
  }

  void interpolate2(int newValue2) {
    //Interpolate values - New value is the incoming value (either 0 or 255) 
    if (storedValue2 != newValue2) counterTime2 = 100;
    if (counterTime2 != 0) counter2++;
    if (counter2 > counterTime2) counter2 = counterTime2;
    percentage2 = map (counter2, 0, 100, 0., 1.);
    interpValue2 = lerp (storedValue2, newValue2, percentage2);
    if (percentage2 == 1.) storedValue2 = newValue2;
    counterTime2 = 0;
  }

  void run() {
    //When setCounter1 is true start counting. When finish,
    //reset setCounter1, and start setCounter2 (and vice versa)
    if (setCounter1) {
      interpolate1(255);
      interpolate2(0);
      counting1 = counting1 + changeSpeed;
      if (counting1 > 1.) {   
        loadFile2();   
        counting1 = 0.;
        setCounter2 = true;
        setCounter1 = false;
      }
    }

    if (setCounter2) {
      interpolate1(0);
      interpolate2(255);
      counting2 = counting2 + changeSpeed;
      if (counting2 > 1.) {
        loadFile1();
        counting2 = 0.;
        setCounter1 = true;
        setCounter2 = false;
      }
    }

    tint(255, interpValue1);
    image(imageOne, 0, 0);

    tint(255, interpValue2);
    image(imageTwo, 0, 0);
  }
}
Tagged:

Answers

  • edited October 2013

    Just had a quick look for now, sorry.
    Unless you've tons of images, it's much better to load them all at once and keep them safe in a PImage[] array.
    Then, when you need to collect some of them, just pick what you need instead of loadImage() all the time! :ar!

  • In case it partially answer your problem, if you need a "dynamic array", use an ArrayList.

  • edited October 2013

    Well my main concern is that even if I use ArrayList, wouldn't this be a problem when I load a new list of images? As you will see in the above example, there is a slideshow - continuous transitions from one image to the other. When a new list of images is available, how can I wait for the transition of the old image to finish, and mix it with the new image without causing any errors?

    My main problem is what happens in the transition of the old vs new images without stopping the slideshow.

  • edited October 2013

    I've already answered that above. loadImage() is a very slow process
    and should be done once within setup() whenever possible! (~~)

  • edited October 2013

    GoToLoop, the image list is not known beforehand, therefore I don't know if there going to be 200 images or 10. For this reason, I will make a separate thread to download all images on the computer, and after this finishes, I start calling one by one the images (load one image and display it, then change it when it has been displayed) - I will not load large images, so to do this while the program is running is not an issue.

    Again, the issue is how to load the new images and delete the old ones, while the slideshow is running.

    Any tips are welcomed!!!

    p.s. I download the image list online after I do a search, and I need to search and download the new images after a specified amount of time, therefore not possible to do this just once in setup

  • loadImage() inside draw() is OK, as long as you do it once in a while, not on each frame (as we see too often).

    Displaying an image can take several seconds, so at the start of this period, you can just quietly load the next image.

    If you need to do a kind of cover flow (sorry, I haven't read the whole thread), you can have an array of 3 or 5 images, and when you display the next image, just shift down the PImages in the array. The oldest one will just be freed from memory (after a while, beware of memory usage) and the latest loaded one will take place at the other end of the array.

  • edited October 2013

    I am also thinking to use a two-dimensional array class. The first array is going to store the events, and the second the images. Then according to my events (if something new occurs, is placed in another array) I can call and get images separately. It sounds logical, but now I have to implement it to see if it works alright.

  • Answer ✓

    Not sure if it is a two-dimensional array or just two arrays of same size...

Sign In or Register to comment.