We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Flashlight effect on multiple videos?
Page Index Toggle Pages: 1
Flashlight effect on multiple videos?? (Read 1916 times)
Flashlight effect on multiple videos??
Jan 25th, 2010, 4:49pm
 
Hi, I'm developing an art installation which deals with interactive projection, and I'm not comfortable enough to do something complex with video using Processing..

I'm not sure if it is possible, but what I've been trying to make is a flashlight effect on video1 that reveals video2 underneath Video1.
The transparent area is movable (follows cursor position) just like a flashlight.
I'm trying to figure out how to specify the active area of tint()...


Does anyone know how to make this happen?

Your help will be really appreciated!!!! Cry

Best

Re: Flashlight effect on multiple videos??
Reply #1 - Jan 26th, 2010, 12:01am
 
Wow, that's a tough one.

Do you want the images to blend together, or would you just like a strict circle of Movie2 playing in the middle of Movie1(centered at the mouse cursor, of course)?

What code do you have so far, if any? Post it.

Can you get your movies to play in Processing, or are they .mov files?
Re: Flashlight effect on multiple videos??
Reply #2 - Jan 26th, 2010, 12:20pm
 
Hi, thanks for your response,

Yes, I'd like to have Movie2 playing in the circle (wherever the cursor is, and yes, in the middle for example) on Movie1. So we'd see other part of Movie2 as we move the cursor.

I started off modifying a simple flashlight effect on image (sorry looks like I can't post active link here yet..):


Code:
// Example 15-9: Adjusting image brightness based on pixel location (Flashlight effect)

import processing.video.*;
Movie movie1;

void setup() {
 size(320, 240, P2D);
 movie1 = new Movie(this, "movie1.mov");
 movie1.loop();
}

void draw() {
 loadPixels();  // Before we deal with pixels
 
  for (int x = 0; x < movie1.width; x++ ) {
   for (int y = 0; y < movie1.height; y++ ) {
     
     // Calculate the 1D pixel location
     int loc = x + y*movie1.width;
     
     // Get the R,G,B values from image
     float r = red (movie1.pixels[loc]);
     float g = green (movie1.pixels[loc]);
     float b = blue (movie1.pixels[loc]);
     
     // Calculate an amount to change brightness
     // based on proximity to the mouse
     float distance = dist(x,y,mouseX,mouseY);
     
     // The closer the pixel is to the mouse, the lower the value of "distance"
     // We want closer pixels to be brighter, however, so we invert the value with the formula: adjustBrightness = (50-distance)/50
     // Pixels with a distance of 50 (or greater) have a brightness of 0.0 (or negative which is equivalent to 0 here)
     // Pixels with a distance of 0 have a brightness of 1.0.
     float adjustBrightness = (50-distance)/50;
     r *= adjustBrightness;
     g *= adjustBrightness;
     b *= adjustBrightness;
     
     // Constrain RGB to between 0-255
     r = constrain(r,0,255);
     g = constrain(g,0,255);
     b = constrain(b,0,255);
     
     // Make a new color and set pixel in the window
     color c = color(r,g,b);
     pixels[loc] = c;
   }
 }
 
 updatePixels();  
}


This worked well with video (.mov). They are simply manipulating brightness of pixels. So I was wondering if I can manipulate alpha values in stead of brightness, so that I can have 2 videos.

My code so far is still pretty much like the example code above..but it is very messy and maybe confusing..


Code:
import processing.video.*;

Movie movie1;
Movie movie2;

void setup(){
 size(320, 240, P2D);
 movie1 = new Movie(this, "movie1.mov");
 movie2 = new Movie(this, "movie2.mov");
 
 movie1.loop();
 movie2.loop();
 
}

void draw(){
   movie1.loadPixels(); // Make the pixels of video available
   
   //video1
    movie1.read();
    image(movie1, 0,0);
   
   //video2
    movie2.read();
    image(movie2, 0,0);

 
 
   for (int x = 0; x < movie1.width; x++ ) {
     for (int y = 0; y < movie1.height; y++ ) {
     
     // Calculate the 1D pixel location on movie1
    int loc = x + y*movie1.width;  
     
    float val = movie1.pixels[loc];
     
     // Calculate an amount to change transparency
     // based on proximity to the mouse
     float distance = dist(x,y,mouseX,mouseY);
     
     float transparency = (50-distance)/50;
      val *= transparency;

      color c = color(255, val);    // color(gray, alpha)
movie1.pixels[loc] = c;
   
   }
 }
     
     updatePixels();  

}



hmmmm... I used color(gray, alpha) instead of tint(). I hope color() works for manipulating opacity. But Movie2 (supposed to be underneath Movie1) is playing on top of Movie1 so I'm not sure if this is working or not.. maybe I should find some ways to make Movie2 as background movie?

I desperately need some thoughts!
Best,
Re: Flashlight effect on multiple videos??
Reply #3 - Jan 27th, 2010, 7:59am
 
You're going to love me in a few minutes.  Grin
Let me just format this so it works with a simple copy and paste.

Replace your draw() in the (second block of) code you posted above with this:

Quote:
void draw(){
  float solidRadius = 20.0; // radius of solid circle.
  float radius = 30.0; // radius of the fading circle.
  movie1.read();
  movie2.read();
  // movie1.loadPixels();
  image(movie2, 0,0);
  loadPixels();  
  for (int x = mouseX-int(radius); x <= mouseX+int(radius); x++ ) {
    for (int y = mouseY-int(radius); y <= mouseY+int(radius); y++ ) {
      if( y < 0 || y >= height || x < 0 || x >= width ){
        continue;
      }
      int loc = x + y*width;
      // if this next line gives you issues, use the commented out one below it instead.  
      color val = movie1.get(x,y);
      // color val = movie1.pixels[loc];
      // And also uncomment the line "movie1.loadPixels();", above.
      float distance = dist(x,y,mouseX,mouseY);
      float transparency = map(radius-(distance-solidRadius), solidRadius, radius, 0.0, 255.0);
      color c = color(red(val), green(val), blue(val), transparency );
      pixels[loc] = distance<radius?blendColor(pixels[loc],c,BLEND):pixels[loc];
      pixels[loc] = distance<solidRadius?val:pixels[loc];
    }
  }
  updatePixels();  
}



Unlike you, I don't have video working in my sketches.
Instead, I had to re-write the sketch so that the movies were actually images.
But since both are treated like pixel data, I don't expect there to be any issues... Hopefully...

That said, I can't test this on actual movies, so it is technically untested code.
All I can tell you is that it works fine for me with my images.
Re: Flashlight effect on multiple videos??
Reply #4 - Jan 27th, 2010, 4:29pm
 
geez I love you!!!
This is beautiful. I learned lots about pixel manipulation from this.
Thank you very much!!!

Only problem I have is that the movie keeps crashing after 30 seconds..getting Invalid memory access error. Sad  should I use different video library? or maybe I should ask on the different topics..?

Anyways, I'm reading through the code to understand how this magic works. (I need to understand it for learning purpose...) So, it'll be great if you can tell if I understood your code right...!

So.., in this code, Movie1 is playing in the circle, and what this code does is to get Movie1 partially (around cursor) playing because the pixels (of Movie1) out of radius size become 100% transparency (invisible)?

Sorry if my understanding is confusing you since I'm still learning programming...
Re: Flashlight effect on multiple videos??
Reply #5 - Jan 27th, 2010, 5:57pm
 
As I said, I can't really help you with video issues, since I can't even get video working in my sketches. Try asking for help in the video forum. What I can do is give some insight into what my own code is doing.

// First we start the draw function
void draw(){

// Define two variables to describe how big the flashlight is.
 float solidRadius = 20.0; // radius of solid circle.
 float radius = 30.0; // radius of the fading circle.

// load up the next frames from each of the videos.
 movie1.read();
 movie2.read();

// if we need to load the pixels of the first video so we can access the pixels[] array of movie1, do so.
 // movie1.loadPixels();

// draw the image of the second video to the screen.
 image(movie2, 0,0);

// load the pixels[] array for what draw() will currently put on the screen if it were to stop right now.
 loadPixels();

// loop about a small square of pixels near the mouse pointer
 for (int x = mouseX-int(radius); x <= mouseX+int(radius); x++ ) {
   for (int y = mouseY-int(radius); y <= mouseY+int(radius); y++ ) {

// if the pixel isn't even on the screen, go on to the next pixel.
     if( y < 0 || y >= height || x < 0 || x >= width ){
       continue;
     }

// determine where in the pixel[] array this pixel is.
     int loc = x + y*width;

// Get the color of the pixel in movie1 at this pixel's location.
     color val = movie1.get(x,y);
     // color val = movie1.pixels[loc];

// Find out how far away from the mouse cursor this pixel is.
     float distance = dist(x,y,mouseX,mouseY);

// use the distance from the mouse cursor to determine how transparent the pixel from movie1 should be.
     float transparency = map(radius-(distance-solidRadius), solidRadius, radius, 0.0, 255.0);

// using this transparency and the color of the pixel in movie1 at this location, create a new color
     color c = color(red(val), green(val), blue(val), transparency );

// If this location is close enough to the mouse to be inside the flashlight area, blend the color we just generated with the pixel we drew with the line "image(movie2,0,0)", storing the result back into the array of pixels at this location.
     pixels[loc] = distance<radius?blendColor(pixels[loc],c,BLEND):pixels[loc];

// If this location is close enough to the mouse to be inside the very center of the flashlight area, overwrite whatever was already in the pixels[] array with movie1's color at this pixel's location.
     pixels[loc] = distance<solidRadius?val:pixels[loc];

// end the for loops for each pixel in the small square.
   }
 }

// use the finished pixel[] array!
 updatePixels();  

// End draw()
}




I also may have an idea as to why you're getting invalid memory access errors. It might be because you just assume that the next frame of the movies are ready to go every time draw() is called. This may not be the case. Look at the second example here:

http://processing.org/reference/libraries/video/movieEvent_.html
Re: Flashlight effect on multiple videos??
Reply #6 - Jan 27th, 2010, 10:22pm
 
Thank you very much for your great help!!
Your comments in the code clarified my mind Smiley

And thank you for the link too! I will try to figure out the video issue and try to shout in the video forum too.
Page Index Toggle Pages: 1