Permalink
Browse files

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.
  • Loading branch information...
1 parent 36ab12a commit a5b224317073513f13b85af4516427bec0a83a1d @hobzcalvin hobzcalvin committed Jun 19, 2013
@@ -0,0 +1,42 @@
+import processing.video.*;
+import processing.net.*;
+import img2opc.*;
+
+/*
+ * This sketch uses the img2opc library to display input from a connected
+ * webcam.
+ */
+
+Capture cam;
+Img2Opc i2o;
+
+int displayWidth = 25;
+int displayHeight = 25;
+
+void setup() {
+ background(0);
+ size(640, 480);
+
+ cam = new Capture(this, 640, 480, 30);
+ cam.start();
+
+ int target = millis() + 1000;
+ while (millis() < target) { }
+
+ i2o = new Img2Opc(this, "127.0.0.1", 7890, displayWidth, displayHeight);
+ i2o.setSourceSize(640, 480);
+}
+
+void draw() {
+ if (cam.available() == true) {
+ set(0, 0, cam);
+
+ new PImage(displayWidth, displayHeight, RGB);
+ cam.read();
+
+ PImage preview = i2o.sendImg(cam);
+
+ image(preview, 0, 0);
+ }
+}
+
@@ -0,0 +1,7 @@
+To use this library, copy or sym-link the entire img2opc directory to your Processing/libraries/ directory.
+
+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.
+
+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
+jar -cf ./library/img2opc.jar ./src/img2opc
+rm -r ./src/img2opc # optional
Binary file not shown.
@@ -0,0 +1,97 @@
+package img2opc;
+import processing.core.*;
+import processing.net.*;
+import java.awt.Color.*;
+
+/*
+ * This library sends images to an OpenPixelControl client.
+ * Width and height arguments passed to the constructor can specify display
+ * size, but currently it assumes a flat display of zigzagging strings like so:
+ *
+ * pixel 0 2h-1 2h
+ * 1 . .
+ * 2 . .
+ * . . .
+ * . . etc.
+ * . h+1
+ * h-1 h
+ */
+
+public class Img2Opc extends PApplet implements PConstants {
+ PApplet parent;
+ int dispWidth;
+ int dispHeight;
+ PImage resizedFrame;
+ int srcx, srcy, srcw, srch;
+ byte[] opcData;
+ Client client;
+ byte[] gamma;
+
+ public Img2Opc(PApplet parent, String host, int port, int w, int h) {
+ this.parent = parent;
+ dispWidth = w;
+ dispHeight = h;
+
+ gamma = new byte[256];
+ for (int i = 0; i < 256; i++) {
+ if (true) {
+ gamma[i] = (byte)(Math.pow((float)(i) / 255.0, 2.5) * 255.0 + 0.5);
+ } else {
+ gamma[i] = (byte)(i);
+ }
+ }
+
+ resizedFrame = new PImage(dispWidth, dispHeight, RGB);
+
+ int numBytes = dispWidth * dispHeight * 3;
+ opcData = new byte[4 + numBytes];
+ // Channel: 0
+ opcData[0] = 0;
+ // Command: 0
+ opcData[1] = 0;
+ // numBytes high and low
+ opcData[2] = (byte)((numBytes >> 8) & 0xFF);
+ opcData[3] = (byte)(numBytes & 0xFF);
+
+ setSourceSize(dispWidth, dispHeight);
+
+ client = new Client(parent, host, port);
+ // The server will hang up after a short period of inactivity.
+ // Send a blank image and hope sendImg() is called soon.
+ sendImg(new PImage(dispWidth, dispHeight));
+ }
+
+ public void setSourceSize(int w, int h) {
+ // TODO: handle other sizes.
+ srch = h;
+ srcw = h;
+ srcx = (w - srcw) / 2;
+ srcy = 0;
+ }
+
+ public PImage sendImg(PImage m) {
+ resizedFrame.copy(m, srcx, srcy, srcw, srch, 0, 0, resizedFrame.width, resizedFrame.height);
+
+ for (int x = 0; x < dispWidth; x++) {
+ for (int y = 0; y < dispHeight; y++) {
+ int c = resizedFrame.pixels[x + y * dispWidth];
+ int pixelPos = 4 + 3 * (x * dispHeight + ((x % 2 == 0) ? y : (dispHeight - 1 - y)));
+ opcData[pixelPos + 0] = gamma[(byte)(c >> 16 & 0xFF) & 0xFF];
+ opcData[pixelPos + 1] = gamma[(byte)(c >> 8 & 0xFF) & 0xFF];
+ opcData[pixelPos + 2] = gamma[(byte)(c >> 0 & 0xFF) & 0xFF];
+ }
+ }
+ if (client != null) {
+ if (client.output != null) {
+ try {
+ client.output.write(opcData);
+ client.output.flush();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ return resizedFrame;
+ }
+}
Binary file not shown.
@@ -0,0 +1,80 @@
+import img2opc.*;
+import processing.video.*;
+import processing.net.*;
+
+/*
+ * This sketch uses the img2opc library to display video files in the data
+ * directory at random.
+ */
+
+Movie m;
+Img2Opc i2o;
+PImage resized;
+int displayWidth = 25;
+int displayHeight = 25;
+Movie endingMovie = null;
+
+void setup() {
+
+ background(0);
+ size(1024, 768);
+
+ i2o = new Img2Opc(this, "127.0.0.1", 7890, displayWidth, displayHeight);
+ loadMovie();
+}
+
+void mousePressed() {
+ if (endingMovie != null) {
+ endingMovie.stop();
+ endingMovie = null;
+ }
+ endingMovie = m;
+ loadMovie();
+ endingMovie.stop();
+ endingMovie = null;
+}
+
+void loadMovie() {
+ m = null;
+
+ java.io.File folder = new java.io.File(dataPath(""));
+ String[] filenames = folder.list();
+
+ String f;
+ do {
+ f = filenames[int(random(filenames.length))]
+ } while (f.equals(".DS_Store"));
+ print("loading '");
+ print(f);
+ println("'");
+ m = new Movie(this, f);
+ m.play();
+ m.read();
+ i2o.setSourceSize(m.width, m.height);
+}
+
+void movieEvent(Movie mov) {
+ if (mov == endingMovie) {
+ return;
+ }
+ mov.read();
+ resized = i2o.sendImg(mov);
+
+ if (mov.time() >= mov.duration() - 0.1) {
+ if (endingMovie != null) {
+ endingMovie.stop();
+ endingMovie = null;
+ }
+ endingMovie = mov;
+ loadMovie();
+ }
+}
+
+void draw() {
+ if (m != null) {
+ image(m, displayWidth, 0);
+ }
+ if (resized != null) {
+ image(resized, 0, 0);
+ }
+}

0 comments on commit a5b2243

Please sign in to comment.