Processing
Børre Stenseth
Skisser >VideoEksplosjon

Video Eksplosjon

Hva

For å spille av video i en Processingskisse må vi kople til et eget bibliotek, video. Dette gjør du ved å velge Tools/Add Tool... Velg libraries og søk etter video.

Begreper som du finner i dokumentasjonen til Processing Video Reference

Movie, play(), available(), read(), loop(), volum(), copy()

I eksempelet nedenfor har vi brukt en mp4-fil som er lagt i data-katalogen i skissen. Fila er fritt tilgjengelige og er hentet fra pixabay.com.

Relevante Skisser
videoExplode

Vi tar deler av videobildet og fordeler på flere frittstående bilder. Vi gjøre dette som en "eksplosjon". Det vil si at vi kaster bildene ut til siden og lar dem finne veien "hjem".

videoExplode

Skissen:

_videoExplode.pde
/*
Eksploder en video i  nxm ruter,
og hent bitene tilbake på plass
*/
import processing.video.*;
// videoen
Movie enVideo;
// er lyden på
boolean lyd=false;
// rutene
ArrayList<vRute>rutene=null;
// antall ruter horisontalt og vertikalt
int rH =10;
int rV =10;
void setup(){
  size(800,600);
  // fri video lastet ned fra pixabay.com/videos/
  enVideo = new Movie(this, "Dance - 4428.mp4");
  // kjør forever
  enVideo.loop();
  // start med lyd
  lyd=true;
  enVideo.volume(1);
  frameRate(20);
}
// del opp videoen i ruter
void setUpRuter(Movie m,int rader,int kolonner){ 
  rutene=new ArrayList();
  int MW=m.width;
  int MH=m.height;
  for(int rad=0;rad< rader;rad++)
    for(int kol=0;kol< kolonner;kol++){
      rutene.add(new vRute(m,
                           kol*MW/kolonner,
                           rad*MH/rader,
                           MW/kolonner,
                           MH/rader));
   }
}
// spre rutene
void eksploder(){
  for(vRute r:rutene){
    r.settTilfeldigPos(width,height);
  }
}
void draw() {
  background(255);
  if(enVideo.available()){
    // instruksjoner
    fill(0);
    text("klikk for å ekplodere\n"+
         "tast: lyd av/på",10,height-30);
    //oppe til venstre på videoen
    translate((width-enVideo.width)/2,
             (height-enVideo.height)/2);
    
    enVideo.read();
    // oppsett av rutene skjer bare en gang,
    // men må skje etter at videoen er lastet 
    // så vi kjenner bredde og hoyde
    if(rutene==null){
      setUpRuter(enVideo,rH,rV);
    }
    // tegn hjemmeposisjon bakerst
    for(int ix=0;ix<rutene.size();ix++){
      rutene.get(ix).tegnHjemmePos();
    }
    // Rutene tegner seg selv på vei hjem
    for(int ix=rutene.size()-1;ix>=0;ix--){
          rutene.get(ix).beregnNesteStegHjemover();
         rutene.get(ix).tegn();
    }
   }
}
// explosjon  
void mouseClicked(){
  eksploder();
}
// lyd av og på
void keyPressed(){
    if (lyd)
       enVideo.volume(0);
     else
       enVideo.volume(1);
     lyd=!lyd;
}

De vandrende rutene er beskrevet slik:

_vRute.pde
/*
Viser fram en del av videobildet
i en bevegelig rute
*/
class vRute{
  // videoen
  Movie mov;
  // hvor vi skal hente rutas innhold fra videoen
  int L; // venstre
  int T; // høyre
  int W; // bredde
  int H; // høyde
  
  // der den befinner seg
  PVector posisjon;
  // der den hører hjemme
  PVector hjemmePosisjon;
  
  // konstruktør
  vRute(Movie mov,int L,int T, int W, int H){
    this.mov=mov;
    this.L=L;
    this.T=T;
    this.W=W;
    this.H=H;
    
    // starter hjemme
    hjemmePosisjon=new PVector(L,T);
    posisjon=new PVector(hjemmePosisjon.x,
                         hjemmePosisjon.y);
  }
  
 void tegnHjemmePos(){
    noFill();
    rect(hjemmePosisjon.x,hjemmePosisjon.y,W,H);
  }
  void tegn(){
    PImage p=createImage(W, H, RGB);
    // kopier fra video
    p.copy(mov,L,T,W,H,0,0,W,H); // L+W,T+H
    // tegn det vi har kopiert
    image(p,posisjon.x,posisjon.y);
  }
  // randomiser posisjonen, eksplosjon
  void settTilfeldigPos(float width,float height){
    posisjon=new PVector(random(-width/2,width),
                         random(-height/2,height));
   }
  
  // alltid på vei hjem
  void beregnNesteStegHjemover(){
    // nesten hjemme, plasser nøyaktig på plass
    if(dist(posisjon.x,posisjon.y,
            hjemmePosisjon.x,hjemmePosisjon.y)<4){
      posisjon=hjemmePosisjon;
      return;
    }
    // flytt med avtagende hastighet
    float dx=(hjemmePosisjon.x-posisjon.x)/15.0;
    float dy=(hjemmePosisjon.y-posisjon.y)/15.0;
    posisjon.x+=dx;
    posisjon.y+=dy;
  }
}
Skisser >VideoEksplosjon