Difference between revisions of "Processing Introduction"

From Interaction Station Wiki
Jump to navigation Jump to search
Line 300: Line 300:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==Draw a image==
+
==Draw a image:==
Let' try to draw an image with Pimage!
+
 
 +
Let' try to draw an image with PImage!
  
 
https://processing.org/reference/PImage.html
 
https://processing.org/reference/PImage.html

Revision as of 12:45, 18 April 2021

Processing

Processing 3 logo.png

Processing is a free graphical library and integrated development environment built for the electronic arts, new media art,

and visual design communities with the purpose of teaching non-programmers the fundamentals of computer programming in a visual context.

Currently, Processing uses the Java language, p5.js (JavaScript), and Processing.py (Python).


https://processing.org/download/


Say Hello

setup()

only run once.

draw()

will continuously repeat the action inside of the {}


1void setup(){
2size(400,400);
3println("Hello!Nan");
4
5}
6void draw(){
7println("welcome to interaction station!");
8}

copy-paste the code above and observe the message from the console.


Now, let's try to draw something

 1void setup(){
 2size(400,400);
 3//println("hello!Nan");
 4background(30,50,80);
 5
 6}
 7void draw(){
 8//println("welcome to nteraction station!");
 9//RGB Value
10stroke(30,150,140);
11line(width/2, height/2, mouseX, mouseY);
12}


Sketch --> Run

Sketch --> Tweak

Sketch --> Present


Full screen!

 1void setup(){
 2//size(400,400);
 3//println("hello!Nan");
 4fullScreen();
 5background(30,50,80);
 6
 7}
 8void draw(){
 9//println("welcome to nteraction station!");
10//RGB Value
11stroke(30,150,140);
12line(width/2, height/2, mouseX, mouseY);
13}

Draw

 1void setup(){
 2//size(400,400);
 3//println("hello!Nan");
 4fullScreen();
 5background(30,50,80);
 6 
 7}
 8void draw(){
 9//println("welcome to interaction station!");
10//RGB Value
11noStroke();
12fill(0,200,0);
13
14ellipse(width/2,height/2,150,150);
15stroke(30,150,140);
16strokeWeight(2);
17line(width/2, height/2, mouseX, mouseY);
18println("mouseX:",mouseX);
19println("mouseY:",mouseY);
20if(mousePressed){
21background(30,50,80);
22}
23}

Communication with Arduino

there are two ways to get processing sketches communicating with microcontrollers.

1. the first one is to use the microcontroller as an HID (Human Interface Device), like a mouse or keyboard.


in this case, we only need to change some code in Arduino IDE.

now. we will use the X and Y values from the motion sensor on CPX to control the position of the nouse.

and left button on CPX to work as mouse left click.

Arduino HID:

 1#include "Mouse.h"
 2#include <Adafruit_CircuitPlayground.h>
 3float X, Y, Z;
 4//int leftButton;
 5bool mouseIsActive = false; 
 6int slideSwitch;
 7
 8void setup() {
 9  // put your setup code here, to run once:
10  CircuitPlayground.begin();
11  Mouse.begin();
12}
13
14void loop() {
15  //read slide switch from cpx.
16  slideSwitch = CircuitPlayground.slideSwitch();
17  // if the switch is on the CPX mouse is active, 
18  if(slideSwitch ==HIGH){
19    mouseIsActive=true;
20    }else{
21      //if the slide switch is off, the cpx mouse will be off
22      mouseIsActive=false;
23      }
24
25  //read the leftButton from cpx
26  int leftButton = CircuitPlayground.leftButton();
27  //x and y position from motion sensor
28  X = CircuitPlayground.motionX();
29  Y = CircuitPlayground.motionY();
30
31  //int xReading=map(x,-1,1,0,100);
32   // if the mouse control state is active, move the mouse with motion sensor X and Y value.
33  if (mouseIsActive) {
34    Mouse.move(X*2, Y*2, 0);
35  }
36
37 // if the mouse is not pressed, press it:
38  if (leftButton==HIGH){
39    if (!Mouse.isPressed(MOUSE_LEFT)) {
40      Mouse.press(MOUSE_LEFT);
41     }
42    }else{  // else the mouse button is not pressed:
43      if (Mouse.isPressed(MOUSE_LEFT)) {
44      Mouse.release(MOUSE_LEFT);
45    }
46      }
47  delay(5);
48}

2. however, sometimes, you want to send data directly from a microcontroller to processing.

in this case, we need to do write few lines of code in both Arduino and processing.

Send out data Arduino IDE:

 1#include <Adafruit_CircuitPlayground.h>
 2float X, Y, Z;
 3void setup() {
 4 Serial.begin(9600);
 5 CircuitPlayground.begin();
 6}
 7
 8void loop() {
 9
10  int leftButton = CircuitPlayground.leftButton();
11  X = CircuitPlayground.motionX();
12  Y = CircuitPlayground.motionY();
13  Z = CircuitPlayground.motionZ();
14  int xVal=map(X,-9,10,0,1920);
15  int yVal=map(Y,-9,10,0,1080);
16
17  Serial.print(xVal);
18  Serial.write('\t');
19  Serial.print(yVal);
20  Serial.write('\t');
21  Serial.println(leftButton);
22  
23  delay(10);
24
25}

Receive the value in Processing:

 1import processing.serial.Serial;
 2//select serial port and set bauds rate
 3static final int PORT_INDEX=6,BAUDS=9600;
 4// create an array, a list of data will be used to store values from snesors.
 5int[] vals= {};
 6
 7void setup(){
 8  noLoop();
 9  frameRate(20);
10  final String[] ports = Serial.list();
11  printArray(ports);
12  new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);
13
14  
15}
16
17void draw(){
18
19   print("x=");
20   println(vals[0]); 
21   print("Y=");
22   println(vals[1]); 
23   print("Button=");
24   println(vals[2]); 
25
26    }
27 
28void serialEvent(final Serial s) {
29  vals = int(splitTokens(s.readString()));
30  redraw = true;
31}

Add the lines back in the code:

 1import processing.serial.Serial;
 2static final int PORT_INDEX=6,BAUDS=9600;
 3int[] vals= {};
 4
 5void setup(){
 6  noLoop();
 7  frameRate(20);
 8  final String[] ports = Serial.list();
 9  printArray(ports);
10  new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);
11
12  fullScreen();
13  background(30,50,130);
14}
15
16void draw(){
17
18  /* print("x=");
19   println(vals[0]); 
20   print("Y=");
21   println(vals[1]); 
22   print("Button=");
23   println(vals[2]); */
24
25    noStroke();
26    fill(255,255,0);    
27    ellipse(width/2,height/2,150,150);
28    stroke(30,170,160);
29    strokeWeight(4);
30    line(width/2, height/2, vals[0], vals[1]);
31    if(vals[2]==1){
32    background(30,50,130);
33    }
34
35 }
36 
37void serialEvent(final Serial s) {
38  vals = int(splitTokens(s.readString()));
39  redraw = true;
40}

Draw a image:

Let' try to draw an image with PImage!

https://processing.org/reference/PImage.html

first, we need to create empty processing and save it somewhere on your computer.

in this case, we created a sketch folder, and inside of the sketch folder,

we need to create a new folder called "data" and save an image (jpg, png, gif,tga)in the "data" folder.


 1PImage images;
 2
 3void setup() {
 4
 5 fullScreen();
 6 images=loadImage("run.gif");
 7}
 8
 9void draw() { 
10 // background(0);
11  image(images,0,0, images.width, images.height );
12  
13  
14}

Image sequence:

Step two:

let's make it move!

in order to do that we need to use a sequence of images.

you can copy the image sequences at the file folder from the physical interfaces@interaction station channel on Teams

 1int numImages=23;
 2int startNumImages=1;
 3PImage[] images= new PImage[numImages];
 4int imgInSeq=1;
 5
 6void setup() {
 7 // size(1920, 1080);
 8 //let's give it a frame rate value so that we can change it later:-))
 9 frameRate(18);
10 fullScreen();
11
12 for (int i = 0; i < numImages; i++) {
13   String imageName = "run-" + nf(i, 5) + ".png";
14   images[i] = loadImage(imageName);
15  }
16}
17
18void draw() { 
19 background(0);
20//we can use % (modulo) to cycle through the images. from 1- to numImages
21imgInSeq= (imgInSeq+1) % numImages;
22image(images[imgInSeq],0,0,images[imgInSeq].width,images[imgInSeq].height);
23
24}


now, let's make it interactive!

remember the first example where we use mouse position to draw lines?

we can also use mouseX position to control the animation.

let's comment out:

1imgInSeq= (imgInSeq+1) % numImages;

and replace it with :

1int imgInSeq = (int)map(mouseX, 0, width, 0, numImages - 1);

now, the images always display from the top left corner. let's move it to the center:

Question Time:

HOW TO DO THAT??

center the image

chose different GIF

Gifgif-250px.gif Cat-maker-250px.gif Alpaca--hoops-250px.gif


Now, let's try it by search online and find your own GIF and make your own image mouse-controlled animated images.

you can use a free online tool GIF frame extractor to split the gif file in image sequence:

https://ezgif.com/split


About renaming the files in sequence:


if you are using macOS, you can just select all the images and right-click select "rename" and chose "format" to rename all your files in sequence.

like this:

Rename-files.png

However:

if you are using Window 10 after you rename a sequence of files, they might look like this: run-(1).png run-(2).png run-(3).png ...

don't panic, you can change the code from

1for (int i = 0; i < numImages; i++) {
2   String imageName = "run-" + nf(i, 5) + ".png";
3   images[i] = loadImage(imageName);
4  }

into

1for (int i = 0; i < numImages; i++) {
2   String imageName = "run-(" + i + ").png";
3   images[i] = loadImage(imageName);
4  }

Sensor controlled image sequnce

1. use the light sensor from CPX to animated the image sequences.

Arduino

 1#include <Adafruit_CircuitPlayground.h>
 2
 3int value;
 4
 5void setup() {
 6  Serial.begin(9600);
 7  CircuitPlayground.begin();
 8}
 9
10void loop() {
11  value = CircuitPlayground.lightSensor();
12  
13 // Serial.print("Light Sensor: ");
14  Serial.println(value);
15  delay(50);
16}

Processing

 1import processing.serial.Serial;
 2static final int PORT_INDEX=6,BAUDS=9600;
 3int [] vals= {};
 4
 5int numImages=97;
 6int startNumImages=1;
 7PImage[] images= new PImage[numImages];
 8int imgInSeq=1;
 9
10void setup() {
11  noLoop();
12  final String[] ports = Serial.list();
13  printArray(ports);
14  new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);
15
16 //let's give it a frame rate value so that we can change it later:-))
17 frameRate(18);
18 fullScreen();
19
20 for (int i = 0; i < numImages; i++) {
21   String imageName = "lego" + nf(i, 5) + ".png";
22   images[i] = loadImage(imageName);
23  }
24}
25
26void draw() { 
27  background(0);
28  println(vals[0]);
29
30
31  imgInSeq = (int)map(vals[0], 0, 500, 0, numImages - 1);
32
33  image(images[imgInSeq],0,0,images[imgInSeq].width,images[imgInSeq].height);
34
35}
36
37void serialEvent(final Serial s) {
38  vals = int(splitTokens(s.readString()));
39  redraw = true;
40}


2. use if condiction and sound sensor to trigger the image sequence to play.

Arduino:
 1#include <Adafruit_CircuitPlayground.h>
 2
 3int value;
 4
 5void setup() {
 6  Serial.begin(9600);
 7  CircuitPlayground.begin();
 8}
 9
10void loop() {
11  // Take 10 milliseconds of sound data to calculate
12  value = CircuitPlayground.mic.soundPressureLevel(10);
13  
14 // Serial.print("Sound Sensor SPL: ");
15  
16  int newVal=map(value,58,102,0,94);
17if (newVal<0){
18  newVal=0;
19    }
20  Serial.println(newVal);
21
22  delay(90);
23}
Processing
 1import processing.serial.Serial;
 2static final int PORT_INDEX=6,BAUDS=9600;
 3int [] vals= {};
 4
 5int numImages=97;
 6int startNumImages=1;
 7PImage[] images= new PImage[numImages];
 8int imgInSeq=1;
 9
10void setup() {
11  noLoop();
12  final String[] ports = Serial.list();
13  printArray(ports);
14  new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);
15
16 //let's give it a frame rate value so that we can change it later:-))
17 frameRate(18);
18 fullScreen();
19
20 for (int i = 0; i < numImages; i++) {
21   String imageName = "lego" + nf(i, 5) + ".png";
22   images[i] = loadImage(imageName);
23  }
24}
25
26void draw() { 
27 background(0);
28 println(vals[0]);
29
30if (vals[0]>400){
31imgInSeq= (imgInSeq+1) % numImages;
32}else{
33  imgInSeq = (int)map(vals[0], 0, 400, 0, numImages - 1);
34}
35
36image(images[imgInSeq],0,0,images[imgInSeq].width,images[imgInSeq].height);
37
38}
39
40void serialEvent(final Serial s) {
41  vals = int(splitTokens(s.readString()));
42  redraw = true;
43}