rgb delayed (solved)

Helou.

whats the way to make a typical RGB delayed video fx.

thks!!

Answers

  • there's nothing built-in, you'll have to code it yourself

    use a circular buffer.

    store images as they become available.

    copy current red pixels, old green pixels and older blue pixels to screen

    (actually, thinking about it, you can store only the green and blue values from the pixels, 1 byte rather than 4. and if you store them in different buffers, the green buffer can be shorter than the blue)

    | red (live, not stored)
    |xxxxx| green (5 frames stored)
    |xxxxxxxxxx| blue (10 frames stored)
    

    (5 and 10 are just examples, adjust depending on delay)

  • well, i need study the buffer.

    some more ideas?

    thks

  • edited February 2017 Answer ✓

    @afonso_castro --

    RGB delayed video

    You mean this kind of effect, correct? https://vimeo.com/59434848

  • edited February 2017

    Yes....i try it in diferents ways.....

    is easy on Pd or max jitter

    but.......

  • edited February 2017

    my working about....some ideas?

    import processing.video.*;
    
    Capture cam;
    
    PImage[] buffer;
    
    int w = 640;
    
    int h = 460;
    
    int nFrames = 10;
    
    int iWrite = 0, iRead = 1;
    
    void setup(){
      size(640,480);
      cam = new Capture(this, w, h);
      cam.start();
      buffer = new PImage[nFrames];
    }
    
    void draw() {
      if(cam.available()) {
        cam.read();
        image(cam,0,0);
    
        buffer[iWrite] = cam.get();
        if(buffer[iRead] != null){
          tint(255,120);
          image(buffer[iRead], 0, 0);
        }
        iWrite++;
        iRead++;
        if(iRead >= nFrames-1){
          iRead = 0;
        }
        if(iWrite >= nFrames-1){
          iWrite = 0;
        }
      }       
    }
    
  • Please edit your post and format your code. Select your code and press ctrl+o and have an empty line above and below your code.

    Kf

  • Answer ✓

    I tried two ways. Below you will find two lines tagged with the key word Effect. Enable only one line at the time to see the results.

    In a nutshell, it displays the latest video plus 9,7,5 frames before, each mask in the following sequence: R,G,B

    EFFECT1: Final results sees the combination of the three color masks.
    EFFECT2: More of a subtle color masking effect

    Kf

    import processing.video.*;
    
    Capture cam;
    
    PImage[] buffer;
    
    int w = 640;
    int h = 460;
    int nFrames = 10;
    int iWrite = 0, iRead = 1;
    
    void setup() { 
      size(640, 480); 
      println(cam.list());
      cam = new Capture(this);//, width,height); 
      cam.start(); 
      buffer = new PImage[nFrames];
    }
    
    void draw() { 
      if (cam.available()) { 
        cam.read(); 
        displayImg(cam, 0xA0ffffff);  //EFECT1: disabled EFFECT2, below
    
        buffer[iWrite] = cam.get();
    
        int _iRead=iRead;
    
        if (buffer[_iRead] != null) {      
          displayImg(buffer[iRead], 0x80ff0000);//Gets red channel and applies an alpha of 0x80 or 128 decimal.
        }
    
        _iRead=nextPos(_iRead,2);
    
        if (buffer[_iRead] != null) {      
          displayImg(buffer[_iRead], 0x4000ff00); //Gets green channel
        }
    
        _iRead=nextPos(_iRead,2);
    
        if (buffer[_iRead] != null) {      
          displayImg(buffer[_iRead], 0x400000ff); //Gets blue channel
        }
    
        //displayImg(cam, 0xA0ffffff); //EFECT2: disabled EFFECT1, above
    
    
    
        iWrite++;
        iRead++;
    
    
        if (iRead == nFrames-1) {
          iRead = 0;
        }
        if (iWrite == nFrames-1) {
          iWrite = 0;
        }
      }
    }
    
    void displayImg(PImage in, int mask) {
    
      PImage cpy = in.get();
      cpy.loadPixels();
      for (int i=0; i<cpy.width*cpy.height; i++) {
        cpy.pixels[i] &=mask;   
      }
      cpy.updatePixels();
      image(cpy, 0, 0);
    }
    
    //Function to find next available proper position, simulating a ring structure
    // cp: current position
    // jump: Steps to jump from current position
    // nFrames: Implicity needed, constrain value of position (aka. size of array)
    int nextPos(int cp,int jump) {
    
      int vr=cp+jump;
    
      if(vr<nFrames)
      return vr;
      //NEXT nFrames=10 and jump=3
      //cp cp+jump  Returned
      // 7   10        0
      // 8   11        1
      // 9   12        2
    
      return vr-nFrames;
    }
    
  • i try to change the code....but i did not It........maybe Safari :(

    I put the code in middle of the (``) but no work

    sorry

  • Answer ✓

    `` are more for single lines of code

    Edit the post, highlight the whole code, press Ctrl-o. The code will indent and should appear OK on a refresh.

  • Well, i was working on sketch and this is the result.

    some more ideas ?

    tks

       import processing.video.*;
    
    Capture cam;
    PImage[] buffer;
    Capture img;
    int w = 640;
    int h = 480;
    int nFrames = 10;
    int[] camR;
    int iWrite = 0, iRead = 1;
    
    void setup(){
      size(640,480);
      cam = new Capture(this, w, h);
      img = new Capture (this, w, h);
      cam.start();
     // for (int i = 0; i < w; i++) {
    
    //for (int j = 0; j < h; j++) {
    
    
    
    //int loc = (cam.width – i – 1) + j*cam.width;
    // iWrite = int (red(cam.pixels[i + j*cam.width/255]));
    //float b = brightness(cam.pixels[loc]);
    }
      }
      buffer = new PImage[nFrames];
    }
    
    void draw() {
      if(cam.available()) {
        cam.read();
        img.read();
        //background(cam);
    
    for (int i = 0; i < width;i++) 
      {
        for (int j = 0; j <height;j++) 
        {
          int loc = i + j*width;
    
          int pixelColour = cam.pixels[loc];
    
          float r = (pixelColour >> 16) & 0xff;
          float g = (pixelColour >> 8) & 0xff;
          float b = pixelColour & 0xff;
          r = (r*1.0);
          g = (g*1.0);
          b = (b*1.0);
           cam.pixels[loc] =  color(0,g,0); 
           img.pixels[loc] = color(r,g,b);        //img=cam;
          img.updatePixels();
          cam.updatePixels();
        }
      }
    
        buffer[iWrite] = cam.get();
    
        if(buffer[iRead] != null){
         // tint(255,200);
           image(buffer[iRead],0,0);
           //  tint(255,100);
          background(img);
    
    
    
       blend(buffer[iRead],0,0,w,h,0,0,w,h,LIGHTEST);
        updatePixels();
    
        }
        iWrite++;
        iRead++;
        if(iRead >= nFrames-1){
          iRead = 0;
        }
        if(iWrite >= nFrames-1){
          iWrite = 0;
        }
      }       
    }
    
  • Answer ✓
    iWrite++;
    iRead++;
    if(iRead >= nFrames-1){
      iRead = 0;
    }
    if(iWrite >= nFrames-1){
      iWrite = 0;
    }
    

    can be rewritten using the % operator

    iWrite = (iWrite++) % nFrames;
    iRead = (iRead++) % nFrames;
    
  • edited February 2017 Answer ✓

    No need for double-reassigning the variables w/ the increment operator: L-)

    iWrite = (iWrite + 1) % nFrames;
    iRead  = (iRead  + 1) % nFrames;
    
  • And finally, i made something like i`d like.

    import processing.video.*;
    Capture myCap;
    Capture G;
    Capture B;
    int capW = 320;
    int capH = 240;
    
    int nDelayFrames = 10; // about 3 seconds
    int nDelayFramesB = 21;
    int currentFrame = nDelayFrames-1;
    int currentFrameB = nDelayFramesB-1;
    PImage frames[];
    PImage framesB[];
    
    void setup() {
      size (640, 480);
      myCap = new Capture(this, width, height);
      G = new Capture(this, width, height);
       B = new Capture(this, width, height);
      myCap.start();
    
      frames = new PImage[nDelayFrames];
      for (int i=0; i<nDelayFrames; i++) {
        frames[i] = createImage(width, height, ARGB);
      }
        framesB = new PImage[nDelayFramesB];
      for (int i=0; i<nDelayFramesB; i++) {
        framesB[i] = createImage(width, height, ARGB);
      } 
    }
    
    void draw() {
      if (myCap.available()) {
        myCap.read();
        G.read();
        B.read();
        for (int d = 0; d < width;d++) 
      {
        for (int j = 0; j <height;j++) 
        {
          int loc = d + j*width;
    
          int pixelColour = myCap.pixels[loc];
    
          float r = (pixelColour >> 16) & 0xff;
          float g = (pixelColour >> 8) & 0xff;
          float b = pixelColour & 0xff;
          r = (r*1.0);
          g = (g*1.0);
          b = (b*1.0);
           myCap.pixels[loc] =   color(r,g,b); 
           G.pixels[loc] = color(0,g*2,0); 
            B.pixels[loc] = color(0,0,b*2);  //img=cam;
          G.updatePixels();
            B.updatePixels();
          myCap.updatePixels();
        }
      }
        frames[currentFrame].loadPixels();
        arrayCopy (G.pixels, frames[currentFrame].pixels);
        frames[currentFrame].updatePixels();
        currentFrame = (currentFrame-1 + (nDelayFrames)) % nDelayFrames;
    
        framesB[currentFrameB].loadPixels();
        arrayCopy (B.pixels, framesB[currentFrameB].pixels);
        framesB[currentFrameB].updatePixels();
        currentFrameB = (currentFrameB-1 + nDelayFramesB) % nDelayFramesB;
      } 
     // tint(0,255,0,160);
      image (frames[currentFrame], 0, 0, width, height);
      //updatePixels();
       //tint(0,0,255,140);
      image (framesB[currentFrameB], 0, 0, width, height);
       tint(255,100);
      image(myCap,0,0,width, height);
    
      }
    
  • edited April 2017

    Hi all, here is a version that is using blend modes instead of tints, the result is an image that is not as tinted and a little bit cleaner code.

        import processing.video.*;
        Capture rCap;
        Capture gCap;
        Capture bCap;
        
        int nDelayFrames = 10; // about 3 seconds
        int nDelayFramesB = 21;
        int currentFrame = nDelayFrames-1;
        int currentFrameB = nDelayFramesB-1;
        PImage frames[];
        PImage framesB[];
        
        void setup() {
          size (640, 480);
          rCap = new Capture(this, width, height);
          gCap = new Capture(this, width, height);
          bCap = new Capture(this, width, height);
          rCap.start();
        
          frames = new PImage[nDelayFrames];
          for (int i=0; i> 16) & 0xff;
                int g = (pixelColour >> 8) & 0xff;
                int b = pixelColour & 0xff;
                rCap.pixels[loc] = color(r, 0, 0); 
                gCap.pixels[loc] = color(0, g, 0); 
                bCap.pixels[loc] = color(0, 0, b);
                rCap.updatePixels();
                gCap.updatePixels();
                bCap.updatePixels();
              }
            }
            frames[currentFrame].loadPixels();
            arrayCopy (gCap.pixels, frames[currentFrame].pixels);
            frames[currentFrame].updatePixels();
            currentFrame = (currentFrame-1 + (nDelayFrames)) % nDelayFrames;
            framesB[currentFrameB].loadPixels();
            arrayCopy (bCap.pixels, framesB[currentFrameB].pixels);
            framesB[currentFrameB].updatePixels();
            currentFrameB = (currentFrameB-1 + nDelayFramesB) % nDelayFramesB;
          }
        
          blendMode(NORMAL);
          // RED
          image(rCap, 0, 0, width, height);
          blendMode(SCREEN);
          // BLUE
          image (framesB[currentFrameB], 0, 0, width, height);
          // GREEN
          image (frames[currentFrame], 0, 0, width, height);
        }
    
  • Hi @kittrick

    Thanks for sharing your answer. However your code doesn't work. You are missing few lines as I have a mismatch curly bracket and there is no draw function in your code.

    Kf

Sign In or Register to comment.