An arraylist of PImages?

edited March 2015 in Questions about Code

Hello!

I'm trying to make a video player for very short loops where the images would be decoded once and for all. So I would like to charge all the images in an arraylist. I have seen ways to do that with an array in the forum, using copy, but I need the flexibility of the arraylist.

The code below seems to load only the last image in the whole arraylist:

// load frames from a video into an arraylist

import processing.video.*;

Movie mov;
ArrayList<PImage> images;
PImage display;
int nImage = 0 ;
int prevImage = 1;

void setup() {
  size(640, 360);
  background(0);

  images = new ArrayList<PImage>();

  mov = new Movie(this, "transit.mov");
  mov.read();
  mov.play();
}


// Loading the frames into the array list
void movieEvent(Movie m) {
  mov.read();
  mov.play();
  images.add(mov);
  image(mov, 0, 0);
  println("loaded " + images.size() + " images");
}


void draw() {

  if (nImage != prevImage && nImage >= 0 && nImage < images.size()  ) {
  image(images.get(nImage), 0, 0);
  prevImage = nImage;
  println("image: " + nImage + " / " + images.size());
  }
}

  // reading the frames with the arrow keys
 void keyPressed() {
  if (key == CODED) {
    if (keyCode == UP) {
      nImage+=1;
    } 
    else if (keyCode == DOWN) {
      nImage-=1;
    }
  } 
} 

Can someone tell me what I'm doing wrong?

Answers

  • edited March 2015

    (edit)

  • A shoot in the dark... I think the play() is called in setup, but actual play only happens in draw, so you probably need to fill your List in draw...

  • Thanks for your anwer _vk! The arraylist should be filled in movieEvent, every time a new image is decoded. The idea is to load a first movie at setup, and to be able to load another one at another time.

  • @corujo== IF i understand what you want:::

    1 problem with your code:: as you have mov.read & mov.play in your movieEvent your arrayList continues allways: you have to add some boolean "if ( isPlaying) (see the code below), then you have also to update your nImage var 2 problem: you have to call the image from your arrayList casting to PImage 3 problem : you have to know (another boolean, "isLoaded", see the code) wether all frames were loaded then you can call te images with your key method. Be aware that at this moment you cannot use the up key (arrayOutOfIndexException) - the same for the down key when you are at the 1 frame from the movie; i have not added that in the code but it is very easy to do. Hoping that that helps...

        // load frames from a video into an arraylist
    
        import processing.video.*;
    
        Movie mov;
        ArrayList<PImage> images;
        PImage display;
        int nImage = 0 ;
        int prevImage = 1;
        boolean isPlaying = false;// NEW
        boolean isLoaded = false;//NEW
    
        void setup() {
          size(640, 360);
          background(0);
    
          images = new ArrayList<PImage>();
    
          mov = new Movie(this, "transit.mov");
          mov.read();
          mov.play();
          isPlaying = true;//NEW
        }
    
    
        // Loading the frames into the array list
        void movieEvent(Movie mov) {
    
    
          mov.read();
         // mov.play();//NO!
        if(isPlaying){
          PImage img = mov.get(); 
         images.add(img);
          nImage++;
    
        }
          println("loaded " + images.size() + " images");
    
        }
    
    
        void draw() {
           verifie();//in order to know wether the movie is over or not
    
           if (isPlaying){
    
             image(mov, 0,0);
           }
    
    
    
         if(isLoaded){// everything has been loaded
    
         image((PImage)images.get(nImage-1), 0, 0);// CASTING to PIMAGE
         prevImage = nImage;
         println("image: " + nImage + " / " + images.size());
    
        }
    
        }
    
        void verifie(){
    
         if ((mov.duration() - mov.time()) <=0.1){
          isPlaying = false; 
          isLoaded = true;
    
        }
        }
    
          // reading the frames with the arrow keys
         void keyPressed() {
          if (key == CODED) {
            if (keyCode == UP && isLoaded) {
              nImage+=1;
            ///here if the code for exception
            } 
            else if (keyCode == DOWN && isLoaded) {
    

    ///here if the code for exception in the arrayList nImage-=1;

            }
          } 
        } 
    
  • Thanks a lot akenaton, I didn't know this method movie.get(), it's not on the processing website's documentation! You answered my question, and even a few more!

  • edited March 2015 Answer ✓

    ... I didn't know this method movie.get()...

    Since Video class inherits from PGraphics, and PGraphics class inherits from PImage,
    all of them share the PImage's get() method: http://processing.org/reference/PImage_get_.html :-B

    That's also the reason why we can directly place a Video instance in the image() function for example,
    which demands a PImage reference as 1 of its parameters: http://processing.org/reference/image_.html ;;)

  • edited March 2015

    Thanks a lot for the pointers GoToLoop! With you help and akenaton's I managed to do what I wanted.

    Here is the code:

        // load frames from a video into an arraylist
        // and play them with arrow keys
    
    
        import processing.video.*;
    
        // adding more access to gstreamer 
        import org.gstreamer.elements.PlayBin2;
        import org.gstreamer.Bus;
        import org.gstreamer.GstObject;
        // trigger a function when the movie has finished playing
        final Bus.EOS finished = new Bus.EOS() {
          @ Override void endOfStream(GstObject elt) {
            stopLoading();
            // println("EOS");
          }
        };
    
        Movie mov;
        String ext = ".mov";
        String firstMovie = "transit" + ext;
        ArrayList<PImage> images;
        int nImage = 0 ;
        int prevImage = 1;
        //  is the movie loading into the arraylist?
        boolean isLoading = false;
    
    
        void setup() {
          size(1024, 768);
          background(0);
          images = new ArrayList<PImage>();
          loadMovie(firstMovie);
        }
    
    
        ////////////////
        // LOAD MOVIE //
        ////////////////
    
        void loadMovie(String movie) {
          background(0); // black screen
          mov = new Movie(this, movie);
          images.clear(); // erase arraylist
          isLoading = true; // stop the draw loop
          mov.playbin.getBus().connect(finished); // listen to end of stream
          mov.read(); 
          mov.play();
        }
    
        // when a new frame is available
        // load it into the arraylist
        void movieEvent(Movie mov) {
          mov.read();
          if(isLoading){
           images.add(mov.get());
           nImage++;
          }  
          println("loaded " + images.size() + " images");
        }
    
        // when end of stream is reached
        // resume the draw loop
        void stopLoading() {
          isLoading = false ;
        }  
    
    
        /////////////////
        // PLAY IMAGES //
        /////////////////
    
        void draw() {
          if (nImage != prevImage && !isLoading) {
          image((PImage)images.get(nImage % images.size()), 0, 0);
          prevImage = nImage;
          println("image: " + nImage);
          }
        }
    
         void keyPressed() {
          if (key == CODED) {
            if (keyCode == UP) {
              nImage+=1;
            } 
            else if (keyCode == DOWN) {
              if (nImage <= 0){
              nImage = (images.size());
              }
              nImage-=1;
            }
          } 
        } 
    
Sign In or Register to comment.