Skip to content

Commit a5b2243

Browse files
committed
Add Processing sketches to display video files and webcam content
Just the start; they only really work with the 25x25-pixel wall in [ freespace ] at the moment. I'm committing the same video file Processing uses in its demos; more files should be added to movie2opc/data/ to make things more interesting.
1 parent 36ab12a commit a5b2243

File tree

6 files changed

+226
-0
lines changed

6 files changed

+226
-0
lines changed
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import processing.video.*;
2+
import processing.net.*;
3+
import img2opc.*;
4+
5+
/*
6+
* This sketch uses the img2opc library to display input from a connected
7+
* webcam.
8+
*/
9+
10+
Capture cam;
11+
Img2Opc i2o;
12+
13+
int displayWidth = 25;
14+
int displayHeight = 25;
15+
16+
void setup() {
17+
background(0);
18+
size(640, 480);
19+
20+
cam = new Capture(this, 640, 480, 30);
21+
cam.start();
22+
23+
int target = millis() + 1000;
24+
while (millis() < target) { }
25+
26+
i2o = new Img2Opc(this, "127.0.0.1", 7890, displayWidth, displayHeight);
27+
i2o.setSourceSize(640, 480);
28+
}
29+
30+
void draw() {
31+
if (cam.available() == true) {
32+
set(0, 0, cam);
33+
34+
new PImage(displayWidth, displayHeight, RGB);
35+
cam.read();
36+
37+
PImage preview = i2o.sendImg(cam);
38+
39+
image(preview, 0, 0);
40+
}
41+
}
42+

Processing/libraries/img2opc/README

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
To use this library, copy or sym-link the entire img2opc directory to your Processing/libraries/ directory.
2+
3+
If you modify the library and want to rebuild its .jar file, run these commands in this directory, replacing the path to Processing's libraries as necessary.
4+
5+
javac -classpath /Applications/Processing.app/Contents/Resources/Java/core/library/core.jar:/Applications/Processing.app/Contents/Resources/Java/modes/java/libraries/net/library/net.jar -d ./src/ ./src/*.java
6+
jar -cf ./library/img2opc.jar ./src/img2opc
7+
rm -r ./src/img2opc # optional
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package img2opc;
2+
import processing.core.*;
3+
import processing.net.*;
4+
import java.awt.Color.*;
5+
6+
/*
7+
* This library sends images to an OpenPixelControl client.
8+
* Width and height arguments passed to the constructor can specify display
9+
* size, but currently it assumes a flat display of zigzagging strings like so:
10+
*
11+
* pixel 0 2h-1 2h
12+
* 1 . .
13+
* 2 . .
14+
* . . .
15+
* . . etc.
16+
* . h+1
17+
* h-1 h
18+
*/
19+
20+
public class Img2Opc extends PApplet implements PConstants {
21+
PApplet parent;
22+
int dispWidth;
23+
int dispHeight;
24+
PImage resizedFrame;
25+
int srcx, srcy, srcw, srch;
26+
byte[] opcData;
27+
Client client;
28+
byte[] gamma;
29+
30+
public Img2Opc(PApplet parent, String host, int port, int w, int h) {
31+
this.parent = parent;
32+
dispWidth = w;
33+
dispHeight = h;
34+
35+
gamma = new byte[256];
36+
for (int i = 0; i < 256; i++) {
37+
if (true) {
38+
gamma[i] = (byte)(Math.pow((float)(i) / 255.0, 2.5) * 255.0 + 0.5);
39+
} else {
40+
gamma[i] = (byte)(i);
41+
}
42+
}
43+
44+
resizedFrame = new PImage(dispWidth, dispHeight, RGB);
45+
46+
int numBytes = dispWidth * dispHeight * 3;
47+
opcData = new byte[4 + numBytes];
48+
// Channel: 0
49+
opcData[0] = 0;
50+
// Command: 0
51+
opcData[1] = 0;
52+
// numBytes high and low
53+
opcData[2] = (byte)((numBytes >> 8) & 0xFF);
54+
opcData[3] = (byte)(numBytes & 0xFF);
55+
56+
setSourceSize(dispWidth, dispHeight);
57+
58+
client = new Client(parent, host, port);
59+
// The server will hang up after a short period of inactivity.
60+
// Send a blank image and hope sendImg() is called soon.
61+
sendImg(new PImage(dispWidth, dispHeight));
62+
}
63+
64+
public void setSourceSize(int w, int h) {
65+
// TODO: handle other sizes.
66+
srch = h;
67+
srcw = h;
68+
srcx = (w - srcw) / 2;
69+
srcy = 0;
70+
}
71+
72+
public PImage sendImg(PImage m) {
73+
resizedFrame.copy(m, srcx, srcy, srcw, srch, 0, 0, resizedFrame.width, resizedFrame.height);
74+
75+
for (int x = 0; x < dispWidth; x++) {
76+
for (int y = 0; y < dispHeight; y++) {
77+
int c = resizedFrame.pixels[x + y * dispWidth];
78+
int pixelPos = 4 + 3 * (x * dispHeight + ((x % 2 == 0) ? y : (dispHeight - 1 - y)));
79+
opcData[pixelPos + 0] = gamma[(byte)(c >> 16 & 0xFF) & 0xFF];
80+
opcData[pixelPos + 1] = gamma[(byte)(c >> 8 & 0xFF) & 0xFF];
81+
opcData[pixelPos + 2] = gamma[(byte)(c >> 0 & 0xFF) & 0xFF];
82+
}
83+
}
84+
if (client != null) {
85+
if (client.output != null) {
86+
try {
87+
client.output.write(opcData);
88+
client.output.flush();
89+
} catch (Exception e) {
90+
e.printStackTrace();
91+
}
92+
}
93+
}
94+
95+
return resizedFrame;
96+
}
97+
}

Processing/movie2opc/data/transit.mov

1.08 MB
Binary file not shown.

Processing/movie2opc/movie2opc.pde

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import img2opc.*;
2+
import processing.video.*;
3+
import processing.net.*;
4+
5+
/*
6+
* This sketch uses the img2opc library to display video files in the data
7+
* directory at random.
8+
*/
9+
10+
Movie m;
11+
Img2Opc i2o;
12+
PImage resized;
13+
int displayWidth = 25;
14+
int displayHeight = 25;
15+
Movie endingMovie = null;
16+
17+
void setup() {
18+
19+
background(0);
20+
size(1024, 768);
21+
22+
i2o = new Img2Opc(this, "127.0.0.1", 7890, displayWidth, displayHeight);
23+
loadMovie();
24+
}
25+
26+
void mousePressed() {
27+
if (endingMovie != null) {
28+
endingMovie.stop();
29+
endingMovie = null;
30+
}
31+
endingMovie = m;
32+
loadMovie();
33+
endingMovie.stop();
34+
endingMovie = null;
35+
}
36+
37+
void loadMovie() {
38+
m = null;
39+
40+
java.io.File folder = new java.io.File(dataPath(""));
41+
String[] filenames = folder.list();
42+
43+
String f;
44+
do {
45+
f = filenames[int(random(filenames.length))]
46+
} while (f.equals(".DS_Store"));
47+
print("loading '");
48+
print(f);
49+
println("'");
50+
m = new Movie(this, f);
51+
m.play();
52+
m.read();
53+
i2o.setSourceSize(m.width, m.height);
54+
}
55+
56+
void movieEvent(Movie mov) {
57+
if (mov == endingMovie) {
58+
return;
59+
}
60+
mov.read();
61+
resized = i2o.sendImg(mov);
62+
63+
if (mov.time() >= mov.duration() - 0.1) {
64+
if (endingMovie != null) {
65+
endingMovie.stop();
66+
endingMovie = null;
67+
}
68+
endingMovie = mov;
69+
loadMovie();
70+
}
71+
}
72+
73+
void draw() {
74+
if (m != null) {
75+
image(m, displayWidth, 0);
76+
}
77+
if (resized != null) {
78+
image(resized, 0, 0);
79+
}
80+
}

0 commit comments

Comments
 (0)