How to draw PGraphics out of an array

Hi all,

i am trying to code an Poster wich takes the color out of the webcam and draws shaps on the canvas. This works finde, but now i want to it to only draw a certain amount of shapes on the canvas, like 50 or so and the old ones should disapper. I have worked it around with drawing a background wich has an opaccity of 10. But this does not look good… Maybe the last 50 shapes can be drawn by an array or so…
Sorry for my bad englisch …

maybe you can help me :slight_smile:

import processing.pdf.*;
import processing.video.*;
Capture video;
PGraphics pg;



//Arrays for the color RGB Value
int[] red = new int[4];
int[] blue = new int[4];
int[] green = new int[4];


//--------------SetUp------------------------------------------------------//
void setup() {  
  size(595, 842); 
  background(255);
  smooth(8);

  //Initialize Capture object via Constructor
  video = new Capture(this, 640, 480);  
  video.start();

  //Begin Record of the PDF
  beginRecord(PDF, "test.pdf");

  //creat Pgraphics 
  pg = createGraphics(595, 842);
}



//--------------Draw--------------------------------------------------------//
void draw() {
  // get 3 colors from the Webcam feed
  color c1 = video.get(329, 380);
  color c2 = video.get(330, 380);
  color c3 = video.get(331, 380);

  //RedValues 
  //Get Int Value of Red
  int redValue1 = int(red(c1));
  int redValue2 = int(red(c2));
  int redValue3 = int(red(c3));

  //safe redValue in Array
  red[0] = redValue1;
  red[1] = redValue2;
  red[2] = redValue3;

  //BlueValues
  //Get Int Value of Blue
  int blueValue1 = int(blue(c1));
  int blueValue2 = int(blue(c2));
  int blueValue3 = int(blue(c3));

  //safe blueValue
  blue[0] = blueValue1;
  blue[1] = blueValue2;
  blue[2] = blueValue3;

  //GreenValues
  //Get Int Value of Green
  int greenValue1 = int(green(c1));
  int greenValue2 = int(green(c2));
  int greenValue3 = int(green(c3));

  //safe greenvalue
  green[0] = greenValue1;
  green[1] = greenValue2;
  green[2] = greenValue3;

  //calculate Brightness of Pixels and generate a Size based on th ebrightness
  float pixBright1 = (redValue1*0.33 + greenValue1*0.5 + blueValue1*0.16);
  int shapeSize1 = int(pixBright1);

  float pixBright2 = (redValue3*0.33 + greenValue3*0.5 + blueValue3*0.16);
  int shapeSize2 = int(pixBright2);

  //Calculate the avarage color of the pixels
  int avgGreen = (greenValue1 + greenValue2 + greenValue3)/3 ;
  int avgRed = (redValue1 + redValue2 + redValue3)/3 ;
  int avgBlue = (blueValue1 + blueValue2 + blueValue3)/3 ;

  //random range
  int ranRange = 11;

  //Calculate the Shapes and their sizes
  int shapeAmount = 20;

  for (int i = 1; i < shapeAmount; i++) {
    pg.beginDraw();
    pg.noStroke();
    pg.fill(avgRed, avgGreen, avgBlue);
    pg.rect(avgRed*random(ranRange)*i, avgBlue*random(ranRange)*i, shapeSize1, shapeSize2, random(50), random(50), random(50), random(50));
    pg.fill(avgRed, avgGreen, avgBlue);
    pg.ellipse(avgRed*random(ranRange)*i, avgBlue*random(ranRange)*i, shapeSize1, shapeSize1); 
    pg.fill(255, 10);
    pg.rect(0, 0, 595,842);

    pg.noFill();
    pg.stroke(avgRed, avgGreen, avgBlue);
    pg.rect(avgRed*random(ranRange)*i, avgBlue*random(ranRange)*i, shapeSize1, shapeSize2, random(50), random(50), random(50), random(50));
    pg.stroke(avgRed, avgGreen, avgBlue);
    pg.ellipse(avgRed*random(ranRange)*i, avgBlue*random(ranRange)*i, shapeSize1, shapeSize1);
    pg.endDraw();
  }


  
  //Draw the PGraphics
  image(pg, 0, 0);

  

  //Safe a PDF on mouseclick
  if (mousePressed==true) {
    endRecord();
  }

  //TestCam
  /*
  image(video, 0, 0);
   fill(255);
   rect(325,380,5,5);
   rect(330,380,5,5);
   rect(335,380,5,5);
   */
}








//--------------Function-----------------------------------------------------//
// An event for when a new frame is available
void captureEvent(Capture video) {  
  // Read the image from the camera.  
  video.read();
}
1 Like

You can do something like this:

PGraphics[] pgArray = new PGraphics[50];
pgArray[0] = createGraphics(595,842);
//Do the same for the other items in the array in the setup() function

If you want the old ones to disappear, the easiest way would be to use a circular list.

Kf

1 Like

Thank you for your help!

i have googled circular list, but i did not really understand how to use this… could you explain how a circular list work ?:slight_smile:

And i dont quit know how i can store the shapes inside the pgraphcs array…

Much thanks
Sh

Ok, PGraphics is not the right approach here. I just understood you wanted multiple PGraphics aka. my mistake, I mistunderstood your question. If you want to store shapes, then you need to store the parameters of your shapes. I don’t understand from your example what a shape is in your use case. A mix of rectangles and ellipses?

Let me do a quick demo of multiple rectangles. I draw 5 items but it always update the oldest entry with the new entry, the core concept of a circular list. I am using an abstract class so you can add define and additional shapes.

Kf



//===========================================================================
// FINAL FIELDS:
final int SIZE=5;
final color[] colList = {
  color(100, 0, 0), 
  color(200, 0, 0), 
  color(100, 100, 0), 
  color(200, 100, 0), 
  color(0, 100, 0), 
  color(0, 200, 0), 
  color(0, 0, 100), 
  color(0, 0, 200), 
  color(100, 0, 100), 
  color(100, 0, 200), 
  color(200, 0, 100), 
  color(200, 0, 200), 
  color(0, 100, 100), 
  color(0, 100, 200), 
  color(0, 200, 100), 
  color(0, 200, 200)
};

//===========================================================================
// GLOBAL VARIABLES:

ShapeThumbPrint[] shapeList;
int listPointer=0;

//===========================================================================
// PROCESSING DEFAULT FUNCTIONS:

void settings() {
  size(400, 600);
}

void setup() {

  textAlign(CENTER, CENTER);
  rectMode(CENTER);

  shapeList=new ShapeThumbPrint[SIZE];
  for (int i=0; i<SIZE; i++) {
    generateAndAddEllipse();
  }
}


void draw() {
  background(0);
  for (int i=0; i<SIZE; i++) {
    shapeList[i].draw();
  }
}

void keyReleased() {
}

void mouseReleased() {
  generateAndAddEllipse();
}


//===========================================================================
// OTHER FUNCTIONS:
void generateAndAddEllipse() {
  color c = colList[int(random(1)*colList.length)];
  float x = random(width);
  float y = random(height);   
  shapeList[listPointer]=new Ellipse(x, y, 50, 50, c);

  listPointer=(listPointer+1)%SIZE;  //Point to next element to update
}

abstract class ShapeThumbPrint{
  public abstract void draw(); 
}

class Ellipse extends ShapeThumbPrint{

  float px;
  float py;
  float w;
  float h;
  color col;

  Ellipse(float x, float y, float ww, float hh, color c) {
    px=x;
    py=y;
    w=ww;
    h=hh;
    col=c;
  }

  void draw() {
    fill(col);
    noStroke(); //no edges
    ellipse(px, py, w, h);
  }
}
2 Likes

thank you for the explenation, you are my hero!

My programming understanding is not that good but i think i now understand the concept of circular list!:slight_smile:

I want to generate the shapes based of the values of the webcam. This works fine in my code. But currently the shapes are drawn endless. But what i want ist that there are only X amount of shapes on the screen.

The Part where i struggle is, how do i load those pgraphics elements in the array, and draw the array?
As you explaind the array works as a circular list if i continously load them in the array and only draw the elements out of the array?

Thank you for your time and help !!!
much appreciated!
sh

1 Like

I got it now!

I have created a background pgraphics which is drawn every fram with opacity 1 and a function wich clears the other pgraphics every 25 frames :slight_smile:

if you are interested in how it looks you can check it out :wink:


import processing.pdf.*;
import processing.video.*;
int overAllCounter = 0;


Capture video;
PGraphics pg, bg;



//Arrays for the color RGB Value
int[] red = new int[4];
int[] blue = new int[4];
int[] green = new int[4];


//--------------SetUp------------------------------------------------------//
void setup() {  
  size(595, 842); 
  background(255);
  smooth(8);

  //Initialize Capture object via Constructor
  video = new Capture(this, 640, 480);  
  video.start();

  //Begin Record of the PDF
  beginRecord(PDF, "test.pdf");

  //creat Pgraphics 
  pg = createGraphics(595, 842);
  bg = createGraphics(595, 842);
}



//--------------Draw--------------------------------------------------------//
void draw() {
  // get 3 colors from the Webcam feed
  color c1 = video.get(329, 380);
  color c2 = video.get(330, 380);
  color c3 = video.get(331, 380);

  //RedValues 
  //Get Int Value of Red
  int redValue1 = int(red(c1));
  int redValue2 = int(red(c2));
  int redValue3 = int(red(c3));

  //safe redValue in Array
  red[0] = redValue1;
  red[1] = redValue2;
  red[2] = redValue3;

  //BlueValues
  //Get Int Value of Blue
  int blueValue1 = int(blue(c1));
  int blueValue2 = int(blue(c2));
  int blueValue3 = int(blue(c3));

  //safe blueValue
  blue[0] = blueValue1;
  blue[1] = blueValue2;
  blue[2] = blueValue3;

  //GreenValues
  //Get Int Value of Green
  int greenValue1 = int(green(c1));
  int greenValue2 = int(green(c2));
  int greenValue3 = int(green(c3));

  //safe greenvalue
  green[0] = greenValue1;
  green[1] = greenValue2;
  green[2] = greenValue3;

  //calculate Brightness of Pixels and generate a Size based on th ebrightness
  float pixBright1 = (redValue1*0.33 + greenValue1*0.5 + blueValue1*0.16);
  int shapeSize1 = int(pixBright1);

  float pixBright2 = (redValue3*0.33 + greenValue3*0.5 + blueValue3*0.16);
  int shapeSize2 = int(pixBright2);

  //Calculate the avarage color of the pixels
  int avgGreen = (greenValue1 + greenValue2 + greenValue3)/3 ;
  int avgRed = (redValue1 + redValue2 + redValue3)/3 ;
  int avgBlue = (blueValue1 + blueValue2 + blueValue3)/3 ;

  //random range
  int ranRange = 11;

  //Calculate the Shapes and their sizes
  int shapeAmount = 5;



  for (int i = 1; i < shapeAmount; i++) {
    pg.beginDraw();
    pg.noStroke();
    pg.fill(avgRed, avgGreen, avgBlue, 255/shapeAmount);
    pg.rect(avgRed*random(ranRange)*i, avgBlue*random(ranRange)*i, shapeSize1, shapeSize2, random(50), random(50), random(50), random(50));
    pg.fill(avgRed, avgGreen, avgBlue, 255/shapeAmount);
    pg.ellipse(avgRed*random(ranRange)*i, avgBlue*random(ranRange)*i, shapeSize1, shapeSize1); 

    pg.noFill();
    pg.stroke(avgRed, avgGreen, avgBlue, 255/shapeAmount);
    pg.rect(avgRed*random(ranRange)*i, avgBlue*random(ranRange)*i, shapeSize1, shapeSize2, random(50), random(50), random(50), random(50));
    pg.stroke(avgRed, avgGreen, avgBlue, 255/shapeAmount);
    pg.ellipse(avgRed*random(ranRange)*i, avgBlue*random(ranRange)*i, shapeSize1, shapeSize1);
    pg.endDraw();
  }
  
  bg.beginDraw();
  bg.noStroke();
  bg.fill(255, 1);
  bg.rect(0, 0, 595, 842);
  bg.endDraw();




  //Draw the PGraphics
  image(bg, 0, 0);
  for ( int i = 0; i<shapeAmount; i++) {
    image(pg, 0, 0);
  }


  

  //Safe a PDF on mouseclick
  if (mousePressed==true) {
    endRecord();
  }

  
  overAllCounter++;
  
  
  if(overAllCounter > 25){
    pg.beginDraw();
    pg.clear();
    pg.endDraw();
    overAllCounter = 0;
  }
  
  println(overAllCounter);
  //TestCam
  /*
  image(video, 0, 0);
   fill(255);
   rect(325,380,5,5);
   rect(330,380,5,5);
   rect(335,380,5,5);
   */
}








//--------------Function-----------------------------------------------------//
// An event for when a new frame is available
void captureEvent(Capture video) {  
  // Read the image from the camera.  
  video.read();
}
2 Likes