Img.mask() doesn't always work when applied to Movie object

Hello,

I am trying to randomly extract parts of a playing video and display them at different draw() cycles.
The code works for most cycles, but sometimes the mask() function looks like it is not applied to the image, so the image is presented in full for just 1 cycles at random cycles. I thought that it may be happening because *mask() takes to long to be computed, so that the next code image() is given an image that has not yet been masked.

Do you know if the above may perhaps be the reason? Would you suggest any approach to solve the issue?

import processing.sound.*;
import processing.video.*;

String media_path = "...a path...";

Movie video1;
int vsq_width = 10;
PShape vertical_square;

void setup() {
  size(1278, 716);
  background(0);
  
  video1 = new Movie(this, media_path + "...a video...");
  video1.play();
}

void draw() {
  background(0);
  
  playVerticalWindow(1);
}

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

void playVerticalWindow(int vsq_amp) {
  for(int i = 0; i < vsq_amp; i++) {
    Movie video_temp = video1;
    PGraphics vrt_img = createGraphics(width, height);
    vrt_img.beginDraw();
    vrt_img.background(0);
    vrt_img.translate(random(width) - vsq_width/2, 0);
    vrt_img.fill(color(255, 255));
    vrt_img.rect(0, 0, vsq_width, height);
    vrt_img.endDraw();
    video_temp.mask(vrt_img);
    image(video_temp, 0, 0, width, height);
  }
}

Hello @lucedan,

I did a quick edit and this works:

import processing.video.*;

Movie video1;
int vsq_width = 50;
PShape vertical_square;

PGraphics vrt_img;
PImage video_temp;

void setup() 
  {
  size(560, 406);  // Size of video
  background(0);

  vrt_img = createGraphics(width, height);

  video1 = new Movie(this, "launch2.mp4");
  video1.loop();
  noLoop();
  }

void draw() {
  background(0);
  if (frameCount>1)
    {
    image(video_temp, 0, 0);
    //image(vrt_img, 0, 0);    
    }
  }

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

void playVerticalWindow() 
  {
  video_temp = video1.copy();
  //image(video_temp, 0, 0);
  //println(video_temp.width, video_temp.height);

  vrt_img.beginDraw();
  vrt_img.background(0, 0);
  vrt_img.translate(vrt_img.width/2, vrt_img.height/2);
  vrt_img.fill(color(255, 255));
  vrt_img.circle(0, 0, 200+50*sin(frameCount*(TAU/180)));
  vrt_img.endDraw();
  //println(vrt_img.width, vrt_img.height);

  video_temp.mask(vrt_img);
  }

image

There may be something useful in there for you.

I used the video in one of the Processing examples.

:)

Hi @glv ,

first of all: thank you very much for spending time in helping me out with the issue. Definitely there is a lot in there for me to learn.

After some experiments, I noticed that transforming

video1.play();

into

video1.loop();
noLoop();

is what makes really the difference. Would you be able to explain to me why is that?

@glv, However, the problem still remains if I try to draw multiple shapes at once, using a for cycle within the playVerticalWindow() method.

void playVerticalWindow() 
  {
  for(int i = 0; i < 10; i++) {
    video_temp = video1.copy();
    vrt_img.beginDraw();
    vrt_img.background(0);
    vrt_img.translate(random(width) - vsq_width/2, 0);
    vrt_img.fill(color(255, 255));
    vrt_img.rect(0, 0, vsq_width, height);
    vrt_img.endDraw();
    video_temp.mask(vrt_img);
  }
  }

I solved the problem like the following (applying the for cycle to the mask rather than to the image).

void playVerticalWindow() 
  {
  video_temp = video1.copy();
  vrt_img.beginDraw();
  vrt_img.background(0);
  for(int i = 0; i < 10; i++) {
    vrt_img.translate(random(width) - vsq_width/2, 0);
    vrt_img.fill(color(255, 255));
    vrt_img.rect(0, 0, vsq_width, height);
    }
  vrt_img.endDraw();
  video_temp.mask(vrt_img);
  }
1 Like