Resizing a Movie - Possible Bug?

edited July 2017 in Library Questions

Hi,

I'm getting some inconsistent behaviour with PImage.width, PImage.height, and PImage.resize() when working with Movie files. Width and height will almost always return 0, though will occasionally return the correct dimensions. PImage.resize() will sometimes throw an error: "Width(0) and Height(0) cannot be <= 0" - even when the dimensions are hardcoded in. I'm posting this here because I'm not sure whether this is a bug or I'm just doing something silly with the code:

macOS 10.12.5; Quicktime 10.4; P3.3.5

import processing.video.*;

Movie m;
PImage mS;
int vScale = 4;
int mW;
int mH;

void setup() {
  size(480, 270);
  m = new Movie(this, "test.mov"); // original dim: 1920 1080
  m.loop();
  mW = m.width; 
  mH = m.height;

  // Almost always returns 0 for both values, but occasionally returns the correct dimensions.  
  println("width: " + mW +" " + "Height: " + mH); 
}

void draw() {
  mS = m.get();

  //This almost never works
  //mS.resize(mW/vScale, mH/vScale); 

  //This works most of the time, but not always!
  //mS.resize(1920/vScale, 1080/vScale); 

  //Again works most of the time, but not always...
  mS.resize(480, 270);


  image(mS, 0, 0);
}

void movieEvent(Movie m) {
 m.read(); 
}

Answers

  • IIRC the movie is played in the background so the size won't be available until the first frame has been decoded. Try ignoring the image in draw() until you get one with some dimensions.

  • That worked, thanks! It seems the simplest method is to just use Movie.available() instead of movieEvent - like this:

    import processing.video.*;
    
    Movie m;
    PImage mS;
    int vScale = 4;
    int mW;
    int mH;
    
    void setup() {
      size(480, 270);
      m = new Movie(this, "test.mov"); 
      m.loop();
    }
    
    void draw() {
      if (m.available()) {
        m.read();
        mW = m.width;
        mH = m.height;
      }
    
      mS = m.get(); 
      mS.resize(mW/vScale, mH/vScale);  
      image(mS, 0, 0);
    }
    
  • edited July 2017

    And if someone wants to use movieEvent, something like this will work:

    import processing.video.*;
    
    Movie m;
    PImage mS;
    int vScale = 4;
    int mW;
    int mH;
    
    boolean gotDim = false;
    
    void setup() {
      size(480, 270);
      m = new Movie(this, "test.mov"); 
      m.loop();
    }
    
    void draw() {  
      if (!gotDim) {
        if (mW == 0 && mH == 0) {
          mW = m.width; 
          mH = m.height;
        } else if (mW > 0 && mH > 0) {
          gotDim = true;
          println("width: " + mW +" " + "Height: " + mH);
        }
      }
    
      if (gotDim) {
        mS = m.get(); 
        mS.resize(mW/vScale, mH/vScale);  
        image(mS, 0, 0);
      }
    }
    
    void movieEvent(Movie m) {
      m.read();
    }
    
  • edited July 2017
    /** 
     * Efficient Movie Resize (v1.0)
     * GoToLoop (2017/Jul/10)
     *
     * Forum.Processing.org/two/discussion/23389/
     * resizing-a-movie-possible-bug#Item_4
     */
    
    import processing.video.Movie;
    PImage frame;
    
    static final String FN = "test", EXT = ".mov";
    static final int SCALE = 4, DELAY = 5, SMOOTH = 3, FPS = 10;
    
    void setup() {
      smooth(SMOOTH);
      initVideo();
    }
    
    void draw() {
      background(frame);
    }
    
    void movieEvent(final Movie m) {
      m.read();
      final PImage img = m.get();
      img.resize(img.width/SCALE, img.height/SCALE);
      frame = img;
    }
    
    void initVideo() {
      final Movie vid = new Movie(this, FN + EXT);
      vid.loop();
      while (vid.height == 0)  delay(DELAY);
      getSurface().setSize(vid.width/SCALE, vid.height/SCALE);
      frameRate(FPS + vid.frameRate);
    }
    
Sign In or Register to comment.