Networking in Processing (Process Blog)

Link to all Video Documentation of Processing Videos:
http://www.youtube.com/user/ProccessingImagery?feature=mhee

The code for GSVideo Library

/**
* GSVideo drawing movie example.
*
* Adapted from Daniel Shiffman’s original Drawing Movie
* example by Andres Colubri
* Makes a movie of a line drawn by the mouse. Press
* the spacebar to finish and save the movie.
*/

import codeanticode.gsvideo.*;

GSMovieMaker mm;
int fps = 30;

void setup() {
size(320, 240);
frameRate(fps);

PFont font = createFont(“Courier”, 24);
textFont(font, 24);

// Save as THEORA in a OGG file as MEDIUM quality (all quality settings are WORST, LOW,
// MEDIUM, HIGH and BEST):
mm = new GSMovieMaker(this, width, height, “drawing.ogg”, GSMovieMaker.THEORA, GSMovieMaker.MEDIUM, fps);

// Available codecs are:
// THEORA
// XVID
// X264
// DIRAC
// MJPEG
// MJPEG2K
// As for the file formats, the following are autodetected from the filename extension:
// .ogg: OGG
// .avi: Microsoft’s AVI
// .mov: Quicktime’s MOV
// .flv: Flash Video
// .mkv: Matroska container
// .mp4: MPEG-4
// .3gp: 3GGP video
// .mpg: MPEG-1
// .mj2: Motion JPEG 2000
// Please note that some of the codecs/containers might not work as expected, depending
// on which gstreamer plugins are installed. Also, some codec/container combinations
// don’t seem to be compatible, for example THEORA+AVI or X264+OGG.

// Encoding with DIRAC codec into an avi file:
//mm = new GSMovieMaker(this, width, height, “drawing.avi”, GSMovieMaker.DIRAC, GSMovieMaker.BEST, fps);

// Important: Be sure of using the same framerate as the one set with frameRate().
// If the sketch’s framerate is higher than the speed with which GSMovieMaker
// can compress frames and save them to file, then the computer’s RAM will start to become
// clogged with unprocessed frames waiting on the gstreamer’s queue. If all the physical RAM
// is exhausted, then the whole system might become extremely slow and unresponsive.
// Using the same framerate as in the frameRate() function seems to be a reasonable choice,
// assuming that CPU can keep up with encoding at the same pace with which Processing sends
// frames (which might not be the case is the CPU is slow). As the resolution increases,
// encoding becomes more costly and the risk of clogging the computer’s RAM increases.

// The movie maker can also be initialized by explicitly specifying the name of the desired gstreamer’s
// encoder and muxer elements. Also, arrays with property names and values for the encoder can be passed.
// In the following code, the DIRAC encoder (schroenc) and the Matroska muxer (matroskamux) are selected,
// with an encoding quality of 9.0 (schroenc accepts quality values between 0 and 10). The property arrays
// can be set to null in order to use default property values.
//String[] propName = { “quality” };
//Float f = 9.0f;
//Object[] propValue = { f };
//mm = new GSMovieMaker(this, width, height, “drawing.ogg”, “schroenc”, “oggmux”, propName, propValue, fps);

// There are two queues in the movie recording process: a pre-encoding queue and an encoding
// queue. The former is stored in the Java side and the later inside gstreamer. When the
// encoding queue is full, frames start to accumulate in the pre-encoding queue until its
// maximum size is reached. After that point, new frames are dropped. To have no limit in the
// size of the pre-encoding queue, set it to zero.
// The size of both is set with the following function (first argument is the size of pre-
// encoding queue):
mm.setQueueSize(50, 10);

mm.start();

background(160, 32, 32);
}

void draw() {
stroke(7, 146, 168);
strokeWeight(4);

// Draw if mouse is pressed
if (mousePressed && pmouseX != 0 && mouseY != 0) {
line(pmouseX, pmouseY, mouseX, mouseY);
}

// Drawing framecount.
String s = “Frame ” + frameCount;
fill(160, 32, 32);
noStroke();
rect(10, 6, textWidth(s), 24);
fill(255);
text(s, 10, 30);

loadPixels();
// Add window’s pixels to movie
mm.addFrame(pixels);

println(“Number of queued frames : ” + mm.getQueuedFrames());
println(“Number of dropped frames: ” + mm.getDroppedFrames());
}

void keyPressed() {
if (key == ‘ ‘) {
// Finish the movie if space bar is pressed
mm.finish();
// Quit running the sketch once the file is written
exit();
}
}

Notes from Feb 7th

We are to make a network experience due Feb. 28th (or maybe the week afterwards).

Is there someway we can work on our previous projects? W
We want to focus on the idea of PLAY
Potential parts of our experience: Interaction, Hardware, Purpose, Audience
Code: Connors and Nicole
Performance: Tamara and Joy

Game: skeptical because could be complicated
Images as the message: creating the media (video, audio). Our interests. netowrk to sumbit and network to view.

Program: Processing Drawing Movie – real time screen record

What will we be learning about creating a network from Green???

Proposal:
Video people drawing – the process, a guess-who game.
Having audience guess who made a video chosen at random. There are multiple author choices to guess from.

Research:
What we don’t want to recreate – flickr (galleries), facebook (public relations).

Notes from Feb 14

Green was away, ill. We still don’t know what he is going to teach us about networking.

We got the processing part to work. Connors said he will figure out how to continuously save after starting a new sketch.

Nicole and Tamara are going to work on the layout
Joy is going to work on the processing sketch aesthetics.

HERE IS THE UPDATED CODE THAT ALLOWS FOR SAVING OF MULTIPLE FILES:
/**
* GSVideo drawing movie example.
*
* Adapted from Daniel Shiffman’s original Drawing Movie
* example by Andres Colubri
* Makes a movie of a line drawn by the mouse. Press
* the spacebar to finish and save the movie.
*/

import codeanticode.gsvideo.*;

GSMovieMaker mm;
int fps = 30;
int moviecounter=0;
void setup() {
size(320, 240);
frameRate(fps);

PFont font = createFont(“Courier”, 24);
textFont(font, 24);
startVideo();
}

void draw() {
stroke(7, 146, 168);
strokeWeight(4);

// Draw if mouse is pressed
if (mousePressed && pmouseX != 0 && mouseY != 0) {
line(pmouseX, pmouseY, mouseX, mouseY);
}

// Drawing framecount.
//String s = “Frame ” + frameCount;
fill(160, 32, 32);
noStroke();
//rect(10, 6, textWidth(s), 24);
fill(255);
//text(s, 10, 30);

loadPixels();
// Add window’s pixels to movie
mm.addFrame(pixels);

println(“Number of queued frames : ” + mm.getQueuedFrames());
println(“Number of dropped frames: ” + mm.getDroppedFrames());
}

void keyPressed() {
if (key == ‘ ‘) {
// Finish the movie if space bar is pressed
mm.finish();
// Quit running the sketch once the file is written
moviecounter++;
startVideo();
}
}

void startVideo() {
// Save as THEORA in a OGG file as MEDIUM quality (all quality settings are WORST, LOW,
// MEDIUM, HIGH and BEST):
mm = new GSMovieMaker(this, width, height, “drawing ” + moviecounter + “.ogg”, GSMovieMaker.THEORA, GSMovieMaker.MEDIUM, fps);

// Available codecs are:
// THEORA
// XVID
// X264
// DIRAC
// MJPEG
// MJPEG2K
// As for the file formats, the following are autodetected from the filename extension:
// .ogg: OGG
// .avi: Microsoft’s AVI
// .mov: Quicktime’s MOV
// .flv: Flash Video
// .mkv: Matroska container
// .mp4: MPEG-4
// .3gp: 3GGP video
// .mpg: MPEG-1
// .mj2: Motion JPEG 2000
// Please note that some of the codecs/containers might not work as expected, depending
// on which gstreamer plugins are installed. Also, some codec/container combinations
// don’t seem to be compatible, for example THEORA+AVI or X264+OGG.

// Encoding with DIRAC codec into an avi file:
//mm = new GSMovieMaker(this, width, height, “drawing.avi”, GSMovieMaker.DIRAC, GSMovieMaker.BEST, fps);

// Important: Be sure of using the same framerate as the one set with frameRate().
// If the sketch’s framerate is higher than the speed with which GSMovieMaker
// can compress frames and save them to file, then the computer’s RAM will start to become
// clogged with unprocessed frames waiting on the gstreamer’s queue. If all the physical RAM
// is exhausted, then the whole system might become extremely slow and unresponsive.
// Using the same framerate as in the frameRate() function seems to be a reasonable choice,
// assuming that CPU can keep up with encoding at the same pace with which Processing sends
// frames (which might not be the case is the CPU is slow). As the resolution increases,
// encoding becomes more costly and the risk of clogging the computer’s RAM increases.

// The movie maker can also be initialized by explicitly specifying the name of the desired gstreamer’s
// encoder and muxer elements. Also, arrays with property names and values for the encoder can be passed.
// In the following code, the DIRAC encoder (schroenc) and the Matroska muxer (matroskamux) are selected,
// with an encoding quality of 9.0 (schroenc accepts quality values between 0 and 10). The property arrays
// can be set to null in order to use default property values.
//String[] propName = { “quality” };
//Float f = 9.0f;
//Object[] propValue = { f };
//mm = new GSMovieMaker(this, width, height, “drawing.ogg”, “schroenc”, “oggmux”, propName, propValue, fps);

// There are two queues in the movie recording process: a pre-encoding queue and an encoding
// queue. The former is stored in the Java side and the later inside gstreamer. When the
// encoding queue is full, frames start to accumulate in the pre-encoding queue until its
// maximum size is reached. After that point, new frames are dropped. To have no limit in the
// size of the pre-encoding queue, set it to zero.
// The size of both is set with the following function (first argument is the size of pre-
// encoding queue):
mm.setQueueSize(50, 10);

mm.start();

background(160, 32, 32);
}

Notes from February 28th:
Revision of idea. Changed from person guessing game into an anonymous art creation and display network. Reference to the art piece Pocket Full of Secrets.

Instructions, could be as simple as “Have fun! Draw something!”

UI Design Tests:
Does it need to be complex, simple, or theme based.

Revision of Idea. Face drawing exercise. Team of 5 people, 1 for each of mouth, eyes (eyebrows optional), nose, hair, ears. Each person goes in 1 after the other and draws a different part as designated by the program.
Why is the user drawing: Because we tell them to. they want to create an character together and create an special memory and experience that they can share.
Why is the user watching: To see their creation realized on the projector, mixed with everyone else’s drawings
Possibility of places the drawn images onto a greater image.

LOOK FOR LIBRARY FOR DRAWING APP.

DRAWING LIBRARY:
http://openprocessing.org/sketch/28505

Proposal
Introduction
Performance, time-based installation or a video installation
a discovery process, surprise. challenging stereotypes
Inspiration: Exquisite Corpse,

Description
A Thousand Faces is a cooperative drawing project that combines user-generated drawings to create surprising images. The piece mirrors the Exquisite Corpse project in terms of spontaneity and collaborative spirit. Since users only contribute a part to the whole, they must abandon ownership of the piece. The end result has a life of its own. The collaborative aspect encourages people to work together and benefit from the surprising joint creation. The piece emphasizes the idea that the sum is greater than the parts and complements the decentralized network system by utilizing every person’s contribution with equal weight to the end creation.

The piece is a composed of input and output components. Contributors are presented with a tablet and a designated space to draw in. Above that space are instructions; “draw a mouth,” “draw eyes,” “draw a nose,” “ draw ears,” or “draw eyebrows.” The user must draw their interpretation of the instructions before receiving a new instruction. Processing creates a two-way network and is constantly checking and sending out signals looking for each submission of instructions. After a user draws one of the following instructions, such as a nose, he must press the ‘submit button’ and a new instruction will appear. The images drawn are sent through the network and displayed on several different bodies on a large screen for the public to see.  Some examples of the images are: a business man, a pirate, an old lady, etc.  The characters have small bodies with large heads to draw more attention to the face, however each face starts as a blank canvas. Once a user presses the submit button the drawn image will transfer to one of the blank faces on the screen in the appropriate spot. The accumulated drawings will create the face. The users are unaware of which face they are drawing, so mix-matching facial features will occur, like a mustache on a woman or an angry face on a grandmother. This challenges the expectations of the public. The secondary user, who has a passive role, will be watching the faces appear on the screen. In general, people tend to form an opinion about physical appearances based on dress. A Thousand Faces challenges this stereotype by placing unlikely faces on familiar character’s bodies and thus changing our perception of the person.

        The piece highlights how simple input data can have deceivingly complex outputs. Protocols are an important part of how the data is managed and presented in a coherent way. The benefit of user-generated data is that no two drawings will be the same and there is no telling what the compiled images will look like. A Thousand Faces is a movement away from stereotypes and embraces diversity in addition to reflecting the unexpectedness found in reality.

////Initialize libraries
//import ddf.minim.*;
////Initialize audio variables
//Minim minim;
//AudioPlayer player;
////Initialize font variables
//PFont txt;
//PFont txt1;
//Initialize colour variables
int colours[][]=new int[10][3];
int position[][]=new int[10][2];
int a;
int b;
int c;
int radii=20;
//Initialize pencil variable
int d=1;

void setup() {
size(800, 480);
colorMode(RGB);
smooth();
background(200);
frameRate(60);
//  //Load font
//  txt=loadFont(“agencyFB.vlw”);
//  txt1=loadFont(“calibri.vlw”);
//Setup background
noFill();
stroke(0);
strokeWeight(3);
rect(0, 0, 799, 479);
//  //Draw instructions
//  fill(0);
//  textFont(txt, 48);
//  text(“Press spacebar to clear the canvas”, 200, 200);
//  textFont(txt, 32);
//  text(“Use the number pad to control line thickness”, 240, 250);
//  textFont(txt, 40);
//  text(“Use left click to draw, and right click to erase”, 190, 300);
//  //Load music
//  minim = new Minim(this);
//  player = minim.loadFile(“chickens.wav”, 2048);
//  player.play();
//  player.loop();
//Add colour palete position values in array
for (int i=0;i<10;i++) {
if (i%2==0) {
position[i][0]=50;
}
else {
position[i][0]=110;
}
}
position[0][1]=160;
position[1][1]=160;
position[2][1]=210;
position[3][1]=210;
position[4][1]=260;
position[5][1]=260;
position[6][1]=310;
position[7][1]=310;
position[8][1]=360;
position[9][1]=360;
//Add colour values in array
//Black
colours[0][0]=0;
colours[0][1]=0;
colours[0][2]=0;
//Grey
colours[1][0]=130;
colours[1][1]=130;
colours[1][2]=130;
//White
colours[2][0]=255;
colours[2][1]=255;
colours[2][2]=255;
//Red
colours[3][0]=255;
colours[3][1]=0;
colours[3][2]=0;
//Orange
colours[4][0]=255;
colours[4][1]=165;
colours[4][2]=0;
//Yellow
colours[5][0]=255;
colours[5][1]=255;
colours[5][2]=0;
//Green
colours[6][0]=0;
colours[6][1]=255;
colours[6][2]=0;
//Blue
colours[7][0]=0;
colours[7][1]=0;
colours[7][2]=255;
//Indigo
colours[8][0]=75;
colours[8][1]=0;
colours[8][2]=130;
//Violet
colours[9][0]=238;
colours[9][1]=130;
colours[9][2]=238;
}
void draw() {
//Call methods
toolbox();
colourPicker();
thickness();

//Drawing tool
if (mousePressed && (mouseButton == LEFT)) line(pmouseX, pmouseY, mouseX, mouseY);
//Eraser
if (mousePressed && (mouseButton == RIGHT)) {
fill(200);
stroke(200);
strokeWeight(7);
line(pmouseX, pmouseY, mouseX, mouseY);
}

//Draw current line thickness
fill(0);
stroke(0);
//we want to create three lines of diff stroke weight to connect to line stroke brush
line(25, 410, 135, 410);
rect(25, 415, 110, 10);
rect(25, 430, 110, 20);
//Reset line thickness for drawing borders etc
strokeWeight(3);
//Clear background
if (keyPressed && key ==’ ‘)clearBG();
}

//Reset Canvas method
void clearBG() {
//Repaint background
fill(200);
stroke(0);
rect(0, 0, 799, 479);
//Reset colour chosen
stroke(a, b, c);
fill(a, b, c);
}

//Adjust pencil thickness method
void thickness() {
if (keyPressed && key ==’1′) d=1;
if (keyPressed && key ==’2′) d=10;
if (keyPressed && key ==’3′) d=20;
//if (keyPressed && key ==’4′) d=7;
//if (keyPressed && key ==’5’) d=9;
//if (keyPressed && key == ‘6’) d=11;
strokeWeight(d);
}

//Draw toolbox method
void toolbox() {
//Panels
fill(60);
stroke(0);
rect(0, 0, 160, 479);
noFill();
rect(0, 0, 799, 479);
//  //Labels
//  fill(255);
//  textFont(txt, 32);
//  text(“Toolbox”, 10, 35);
//  textFont(txt, 16);
//  text(“Current Colour”, 10, 65);
//  text(“Colours”, 10, 132);
//  text(“Current line thickness”, 10, 410);
//  textFont(txt1, 12);
//  text(“© Crwire 2011”, 75, 475);
//Lines/Borders
fill(0);
/*
rect(9, 69, 142, 32);
line(0, 43, 160, 43);
line(0, 110, 160, 110);
line(0, 390, 160, 390);
noFill();
rect(9, 420, 142, 32);*/
//Colour palete
for (int i=0;i<10;i++) {
fill(colours[i][0], colours[i][1], colours[i][2]);
ellipse(position[i][0], position[i][1], 40, 40);
}
//Reset fill colour
fill(a, b, c);
//Current colour box
stroke(0);
rect(10, 70, 140, 30);
//Reset stroke colour
stroke(a, b, c);
}

//Colour palete detection and selector method
void colourPicker() {
for (int i=0;i<10;i++) {
if ((dist(position[i][0], position[i][1], mouseX, mouseY)<radii)) {
fill(colours[i][0], colours[i][1], colours[i][2]);
stroke(0);
ellipse(position[i][0], position[i][1], 50, 50);
if (mousePressed && (mouseButton == LEFT)) {
a=colours[i][0];
b=colours[i][1];
c=colours[i][2];
}
}
}
}

CODE FOR THE SERVER AND CLIENT!!!!! (WITHOUT DRAWING APPLICATION!!!!!!!!11!!!!1111!!!!!1ONE!!!)

Server Code:
//NETWORK CONNECTION CODE BASED ON  CODE FROM LEARNING PROCESSING, BY DANIEL SHIFFMAN

// Import the net libraries
import processing.net.*;
// Declare a server
Server server;
boolean clientReady = false;
String incomingMessage = “”;
PImage recievedImage;
color pixelData;
color incomingColor;
String incomingColorString;
boolean whileReading;

void setup() {
size(640, 400);
// Create the Server on port 5204
server = new Server(this, 5204);
recievedImage = loadImage(“test.jpg”);
recievedImage.loadPixels();
}

void draw() {
Client client = server.available();
// We should only proceed if the client is not null
if (client!= null) {
incomingMessage = waitForAnswer(client);
if (incomingMessage.equals(“ready”)) {
server.write(“ready\n”);
println(“info sent”);
clientReady=true;
whileReading = true;
}
for (int i = 0; i <width*height; i++) {
incomingColorString = waitForAnswer(client);
String[] parts = incomingColorString.split(” “);
int remote_i = int(parts[0]);
incomingColor = int(parts[1]);
//println(incomingColor);
//pixelData = incomingColor;
recievedImage.pixels[i] = incomingColor;
if ((i+1) % 1024 == 0 ) {
server.write(“ready\n”);
println(“keep going ” + i);
}
}
println(“done”);
clientReady=false;
incomingMessage = “”;
recievedImage.loadPixels();
image(recievedImage, 0, 0);
}
}

String waitForAnswer(Client client) {
String messageFromServer = null;
while (messageFromServer == null) {
messageFromServer = client.readStringUntil(‘\n’);
if (messageFromServer != null) {
messageFromServer = messageFromServer.trim();
return messageFromServer;
}
}
return null;
}

CLIENT CODE:
//NETWORK CONNECTION CODE BASED ON CODE FROM LEARNING PROCESSING, BY DANIEL SHIFFMAN

// Import the net libraries
import processing.net.*;
// Declare a client
Client client;
PImage faceImage;
boolean serverReady = false;
color pixelData;
// A String to hold whatever the server says
String messageFromServer = “”;
// A String to hold what the user types
String typing =””;

void setup() {
size(640, 400);
// Create the Client, connect to server at 127.0.0.1 (localhost), port 5204
client = new Client(this, “141.117.229.87”, 5204);
faceImage = loadImage(“Untitled.jpg”);
image(faceImage, 0, 0);
faceImage.loadPixels();
}

void draw() {
}

// Simple user keyboard input
void keyPressed() {
// If the return key is pressed, save the String and clear it
if (key == ‘\n’) {
client.write(“ready\n”);
String messageFromServer = waitForAnswer();
if (messageFromServer.equals(“ready”)) {
println(“good to go”);
}
// send the data
for (int i = 0; i < width*height; i++) {
pixelData = faceImage.pixels[i];
client.write(i + ” ” + pixelData + ‘\n’);
if ((i+1) % 1024 == 0) {
//delay(50);
println(“waiting for server” + i);
String msgFromServer = waitForAnswer();
if (msgFromServer.equals(“ready”)) {
println(“keep going ” + i);
}
}
}
println(“Done!”);
}
}

String waitForAnswer() {
String messageFromServer = null;
while (messageFromServer == null) {
messageFromServer = client.readStringUntil(‘\n’);
if (messageFromServer != null) {
messageFromServer = messageFromServer.trim();
return messageFromServer;
}
}
return null; // this should never happen
}

Recent Network Canvas Code March 23 2012 424PM

/*Fix the stroke, submit, differentiate the canvas from the palette*/
//Text
PFont F;
//Initialize colour variables
int colours[][]=new int[10][3];
int position[][]=new int[10][2];
int a;
int b;
int c;
int radii=20;
//Initialize pencil variable
int d=1;
int f=3;

void setup() {
size(800, 480);
colorMode(RGB);
smooth();
background(200);
frameRate(60);
//text
F=loadFont(“DialogInput-30.vlw”);
//Setup background
noFill();
stroke(0);
strokeWeight(f);
rect(0, 0, 799, 479);

//Add colour palete position values in array
for (int i=0;i<10;i++) {
if (i%2==0) {
position[i][0]=50;
}
else {
position[i][0]=110;
}
}
position[0][1]=160;
position[1][1]=160;
position[2][1]=210;
position[3][1]=210;
position[4][1]=260;
position[5][1]=260;
position[6][1]=310;
position[7][1]=310;
position[8][1]=360;
position[9][1]=360;
//Add colour values in array
//Black
colours[0][0]=0;
colours[0][1]=0;
colours[0][2]=0;
//Grey
colours[1][0]=130;
colours[1][1]=130;
colours[1][2]=130;
//White
colours[2][0]=255;
colours[2][1]=255;
colours[2][2]=255;
//Red
colours[3][0]=255;
colours[3][1]=0;
colours[3][2]=0;
//Orange
colours[4][0]=255;
colours[4][1]=165;
colours[4][2]=0;
//Yellow
colours[5][0]=255;
colours[5][1]=255;
colours[5][2]=0;
//Green
colours[6][0]=0;
colours[6][1]=255;
colours[6][2]=0;
//Blue
colours[7][0]=0;
colours[7][1]=0;
colours[7][2]=255;
//Indigo
colours[8][0]=75;
colours[8][1]=0;
colours[8][2]=130;
//Violet
colours[9][0]=238;
colours[9][1]=130;
colours[9][2]=238;
}
void draw() {
//Call methods
toolbox();
colourPicker();
thickness();
//text
fill(0);
textFont(F,30);
text(“Enter”, 700, height-20);
text(“Clear”,175, height-20);
//Drawing tool
if (mousePressed && (mouseButton == LEFT)) line(pmouseX, pmouseY, mouseX, mouseY);
//Eraser
if (mousePressed && (mouseButton == RIGHT)) {
fill(200);
stroke(200);
strokeWeight(7);
line(pmouseX, pmouseY, mouseX, mouseY);
}

//Reset line thickness for drawing borders etc
strokeWeight(f);
//Clear background
if (keyPressed && key ==’ ‘)clearBG();
}

//Reset Canvas method
void clearBG() {
//Repaint background
fill(200);
stroke(0);
rect(0, 0, 799, 479);
//Reset colour chosen
stroke(a, b, c);
fill(a, b, c);
}

void thickness(){
if(mouseX>25 && mouseY==410 && mouseX<160 && mousePressed) d=1;
if(mouseX>25 && mouseY>415 && mouseX<135 && mouseY<425 && mousePressed) d=10;
if(mouseX>25 && mouseY>430 && mouseX<135 && mouseY<450 && mousePressed) d=20;
strokeWeight(d);
}

//Draw toolbox method
void toolbox() {
//Panels
fill(60);
stroke(0);
rect(0, 0, 160, 479);
noFill();
rect(0, 0, 799, 479);

//Draw current line thickness
fill(0);
stroke(0);
//we want to create three lines of diff stroke weight to connect to line stroke brush
line(25, 410, 135, 410);
rect(25, 415, 110, 10);
rect(25, 430, 110, 20);
//Lines/Borders
fill(0);

//Colour palete
for (int i=0;i<10;i++) {
fill(colours[i][0], colours[i][1], colours[i][2]);
ellipse(position[i][0], position[i][1], 40, 40);
}
//Reset fill colour
fill(a, b, c);
//Current colour box
stroke(0);
rect(10, 70, 140, 30);
//Reset stroke colour
stroke(a, b, c);
}

//Colour palete detection and selector method
void colourPicker() {
for (int i=0;i<10;i++) {
if ((dist(position[i][0], position[i][1], mouseX, mouseY)<radii)) {
fill(colours[i][0], colours[i][1], colours[i][2]);
stroke(0);
ellipse(position[i][0], position[i][1], 50, 50);
if (mousePressed && (mouseButton == LEFT)) {
a=colours[i][0];
b=colours[i][1];
c=colours[i][2];
}
}
}
}

NOTES

Peoples faces are 400X400, and canvas is 640X480
Section of processing sketch that drawing area occupies is from 163,3 to 797,476

1. the head will be part of the canvas. Do random skin color (different shades)
[Joy:  if there is color for skin, the user’s drawing have to be no background inoreder to fit on the face. Otherwise, it will be white box of background box on every piece of drawing.]

2. The submit button…. [I did ENTER instead… not sure if that is okey…]
3. saving the PImage

Joy: here is the ten character I made. I do not know if the face size could be change in the code? otherwise, I will change the circle on the character.

FINALIZED CODE FOR CLIENT AND SERVER

Server:
//NETWORK CONNECTION CODE BASED ON CODE FROM LEARNING PROCESSING, BY DANIEL SHIFFMAN

// Import the net libraries
import processing.net.*;
// Declare a server
Server server;
boolean clientReady = false;
String incomingMessage = “”;
PImage recievedImage;
color pixelData;
color incomingColor;
String incomingColorString;
boolean whileReading;
PImage bodyImage;
int randImage;
int personCounter = 0;
boolean personOne = false;
boolean personTwo = false;
boolean personThree = false;

void setup() {
size(1680, 1050);
background(255);
// Create the Server on port 5204
server = new Server(this, 5204);
recievedImage = loadImage(“face.jpg”);
recievedImage.loadPixels();
for (int i = 0; i<3; i++) {
chooseRandomPerson();
personCounter++;
if (personCounter==3) {
personCounter = 0;
}
}
}

void draw() {
Client client = server.available();
// We should only proceed if the client is not null
if (client!= null) {
incomingMessage = waitForAnswer(client);
if (incomingMessage.equals(“ready”)) {
server.write(“ready\n”);
println(“info sent”);
clientReady=true;
whileReading = true;
}
for (int i = 0; i <540*480; i++) {
incomingColorString = waitForAnswer(client);
String[] parts = incomingColorString.split(” “);
int remote_i = int(parts[0]);
incomingColor = int(parts[1]);
//println(incomingColor);
//pixelData = incomingColor;
recievedImage.pixels[i] = incomingColor;
if ((i+1) % 1024 == 0 ) {
server.write(“ready\n”);
println(“keep going ” + i);
}
}
println(“done”);
clientReady=false;
incomingMessage = “”;
recievedImage.loadPixels();
placeFace();
recievedImage = loadImage(“face.jpg”);
recievedImage.loadPixels();
}
}

String waitForAnswer(Client client) {
String messageFromServer = null;
while (messageFromServer == null) {
messageFromServer = client.readStringUntil(‘\n’);
if (messageFromServer != null) {
messageFromServer = messageFromServer.trim();
return messageFromServer;
}
}
return null;
}

void chooseRandomPerson() {
randImage = int(random(8));
bodyImage = loadImage(randImage + “.jpg”);
if (personCounter == 0) {
image(bodyImage, 120, 125);
}
else if (personCounter == 1) {
image(bodyImage, 600, 125);
}
else if (personCounter == 2) {
image(bodyImage, 1080, 125);
}
}

void placeFace() {
if (personCounter == 0) {
image(recievedImage, 85, 45);
personCounter++;
chooseRandomPerson();
}
else if (personCounter == 1) {
image(recievedImage, 560, 45);
personCounter++;
chooseRandomPerson();
}
else if (personCounter == 2) {
image(recievedImage, 1050, 45);
personCounter = 0;
chooseRandomPerson();
}
}
Client:
//NETWORK CONNECTION CODE BASED ON CODE FROM LEARNING PROCESSING, BY DANIEL SHIFFMAN

//————————DRAWING APP CODE——————–
//Call methods
toolbox();
colourPicker();
thickness();
//text
fill(0);
textFont(F, 30);
text(” Enter To Send Face”, 10, 10, 200, 200);
//Drawing tool
if (mousePressed && (mouseButton == LEFT)) line(pmouseX, pmouseY, mouseX, mouseY);
//Eraser
if (mousePressed && (mouseButton == RIGHT)) {
fill(255);
stroke(255);
strokeWeight(7);
line(pmouseX, pmouseY, mouseX, mouseY);
//Reset line thickness for drawing borders etc
strokeWeight(f);
//Clear background
if (keyPressed && key ==’ ‘)clearBG();
}
}

// Simple user keyboard input
void keyPressed() {
// If the return key is pressed, save the String and clear it
if (key == ‘\n’) {
for (int y = 0 ; y < 480;y++) {
for (int x = 0; x <540;x++) {
faceImage.pixels[counter] = get(x+160, y);
counter++;
}
}
client.write(“ready\n”);
String messageFromServer = waitForAnswer();
if (messageFromServer.equals(“ready”)) {
println(“good to go”);
}
// send the data
for (int i = 0; i < 540*480; i++) {
pixelData = faceImage.pixels[i];
client.write(i + ” ” + pixelData + ‘\n’);
if ((i+1) % 1024 == 0) {
//delay(50);
println(“waiting for server” + i);
String msgFromServer = waitForAnswer();
if (msgFromServer.equals(“ready”)) {
println(“keep going ” + i);
}
}
}
println(“Done!”);
drawface();
}
}

String waitForAnswer() {
String messageFromServer = null;
while (messageFromServer == null) {
messageFromServer = client.readStringUntil(‘\n’);
if (messageFromServer != null) {
messageFromServer = messageFromServer.trim();
return messageFromServer;
}
}
return null; // this should never happen
}

//Reset Canvas method
void clearBG() {
//Repaint background
fill(255);
stroke(0);
rect(0, 0, 799, 479);
//Reset colour chosen
stroke(a, b, c);
fill(a, b, c);
}

void thickness() {
if (mouseX>25 && mouseY==410 && mouseX<160 && mousePressed) d=1;
if (mouseX>25 && mouseY>415 && mouseX<135 && mouseY<425 && mousePressed) d=10;
if (mouseX>25 && mouseY>430 && mouseX<135 && mouseY<450 && mousePressed) d=20;
strokeWeight(d);
}

//Draw toolbox method
void toolbox() {
//Panels
fill(60);
stroke(0);
//  strokeWeight(0);
noStroke();
rect(0, 0, 160, 479);
noFill();
rect(0, 0, 799, 479);
strokeWeight(f);

//Draw current line thickness
fill(0);
stroke(0);
//we want to create three lines of diff stroke weight to connect to line stroke brush
line(25, 410, 135, 410);
rect(25, 415, 110, 10);
rect(25, 430, 110, 20);
//Lines/Borders
fill(0);

//Colour palete
for (int i=0;i<10;i++) {
fill(colours[i][0], colours[i][1], colours[i][2]);
ellipse(position[i][0], position[i][1], 40, 40);
}
//Reset fill colour
fill(a, b, c);
//Current colour box
stroke(0);
rect(10, 90, 140, 30);
//Reset stroke colour
stroke(a, b, c);
}

//Colour palete detection and selector method
void colourPicker() {
for (int i=0;i<10;i++) {
if ((dist(position[i][0], position[i][1], mouseX, mouseY)<radii)) {
fill(colours[i][0], colours[i][1], colours[i][2]);
stroke(0);
ellipse(position[i][0], position[i][1], 50, 50);
if (mousePressed && (mouseButton == LEFT)) {
a=colours[i][0];
b=colours[i][1];
c=colours[i][2];
}
}
}
}

void drawface() {
background(255);
//  fill(255,0,0);
noStroke();
//  rect(163,3,634,473);
fill(random(255), random(255), random(255));
ellipse(430, 280, 400, 400);
counter = 0;
}

Advertisements

About Connors Eilersen

I am a graduate (BFA) of Ryerson University, and I like to make things, design things, and think things.
This entry was posted in Process Blog. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s