xforce30164:
I'd be great if you could do the switch one so i can get an idea of your way or programming and thinking.
Yeah thats what I decided on so I spent some time reworking it so that it would work either way. I also added a switch so you could just run it onscreen and not actually output the serial, this made testing parts of the code much quicker. I have tried to comment as fully as possible, I have probably gone overboard :D. Let me know what you think. The Arduino part of the code is already up in other posts in this thread.
/*
* ShiftMatrixPWM Serial Video Transmit for Processing
* by Richard Black
* Built-in video library replaced with gsvideo by Andres Colubri
* Get it from: http://gsvideo.sourceforge.net/
*
* Loads a video file and downscales the frames and sends them
* via Serial to an Arduino setup with the ShiftMatrixPWM Library.
* For the Arduino, found at: http://arduino.cc/forum/index.php/topic,66988.0.html
* This displays three images in the window. The original, the down
* scaled and the final output. This code has been setup to work with
* video's in 4:3 ratio but you could adapt it for other ratios.
* It is currently set to output 32 levels of brightness. This can be changed.
*/
import codeanticode.gsvideo.*;
import processing.serial.*;
//SETTINGS START HERE!!!!!!!!!!
//currently I am building a square matrix. I left seperate height and width
//for future possible use.
boolean ColourMatrix = false; // true for colour, false for Mono
boolean OutputEnabled = false; // true for serial out, false no serial out(on screen only)
int mpHigh = 64; //Number of Rows High the Matrix is.
int mpWide = 64; //Number of Columns wide the Matrix is.
int movRate = 40; //Set the number of frames per sec to process
String comPort = "COM5"; //Set what port the Arduino is on
String movFile = "video.mp4"; //set which file to play. This needs to be in the projects data folder
int brightLevel = 32; //This is the number of levels required. On the Arduino this would be 0-31
//using this code bightLevel should be a multiple of 8 so it can be cleanly divided into 256 as further down
//SETTINGS END HERE!!!!!!!!!!!!
Serial matrixPort;
GSMovie theMovie; //Creates the GSvideo Movie object.
PImage smallFrame = new PImage(mpWide, mpHigh);
color pixelclr; //this is for color setup
int pixelbright; //this is for mono color setup
byte [] myFrame;
PFont font;
int divider = 256 / brightLevel; //This allows calculating the brightness levels in the code
void setup() {
size(1000, 400, P3D);
if (ColourMatrix==true){
myFrame = new byte[mpWide*3*mpHigh];
} else {
myFrame = new byte[mpWide*mpHigh];
}
matrixPort = new Serial(this, comPort, 250000);// Initialise com port replace with your speed
frameRate(movRate);//framerate set above in settings
noStroke();
background(0);
theMovie = new GSMovie(this, movFile); //Initialises instance of the movie
theMovie.loop(); // I have it looping. You can comment this out if you don't want looping
//theMovie.play(); // Use this to have the movie only play once. No Repeat.
ellipseMode(CORNER);
font = loadFont("DejaVuSans-24.vlw"); //Change to whatever font file you have otherwise, comment out
//comment out the next five lines if there is no font or above is commented out
textFont(font);
fill(0, 102, 153);
text("Original", 15, theMovie.height+20); // Label
text("Down Scaled", theMovie.width+20, (smallFrame.height*2)+20);// Label
text("Output", theMovie.width+20, (height/2)-10);// Label
}
// Read new values from movie
void movieEvent(GSMovie m) {
m.read();// Reads in the new Frame of the movie
//This next line takes the movie frame and resizes it into a smaller PImage object.
smallFrame.copy(m, m.width/8, 0, int(m.width-(m.width/4)), m.height, 0, 0, smallFrame.width, smallFrame.height);
//This also only gets the center part of the video as the ratio is not a perfect
//square. The left and right edges get trimed. Currently this is set for 4:3 ratio to square (ie the matrix)
}
// Display values from movie
void draw() {
image(smallFrame,theMovie.width+10,0,smallFrame.width*2,smallFrame.height*2); //Draws the small Frame
//image(theMovie,0,0,theMovie.width/2,theMovie.height/2); //Draws the full movie Frame, half size optional
image(theMovie,0,0);//Draws the full movie Frame
for (int y = 0; y < smallFrame.height;y++) {
for (int x = 0; x < smallFrame.width;x++) {
if (ColourMatrix==false){
pixelbright = int(brightness(smallFrame.pixels[(y*smallFrame.width)+x])/divider);
myFrame[(y*smallFrame.width)+x]=byte(pixelbright);
fill(pixelbright*divider);
} else {
pixelclr = smallFrame.pixels[(y*smallFrame.width)+x];
if (red(pixelclr)/divider < 1) {
myFrame[(y*smallFrame.width*3)+(x*3)]=byte(0);
} else {
myFrame[(y*smallFrame.width*3)+(x*3)]=byte(int(pow(31,(red(pixelclr)/divider)/31)));
}
if (green(pixelclr)/divider < 1) {
myFrame[(y*smallFrame.width*3)+(x*3)+1]=byte(0);
} else {
myFrame[(y*smallFrame.width*3)+(x*3)+1]=byte(int(pow(31,(green(pixelclr)/divider)/31)));
}
if (blue(pixelclr)/divider < 1) {
myFrame[(y*smallFrame.width*3)+(x*3)+2]=byte(0);
} else {
myFrame[(y*smallFrame.width*3)+(x*3)+2]=byte(int(pow(31,(blue(pixelclr)/divider)/31)));
}
fill((red(pixelclr)/divider)*divider,(green(pixelclr)/divider)*divider,(blue(pixelclr)/divider)*divider);
}
//The ellipse is for drawing the supposed output using the colour/brightness from the Fill above
ellipse(x*((width/4)/mpWide)+(theMovie.width+10),(height/2)+(y*((height/2)/mpHigh)),((width/4)/mpWide)-1,((height/2)/mpHigh));
}
}
//println(myFrame); //used to print frame data to the output panel, good for testing
if (OutputEnabled==true){
matrixPort.write('~'); // start Character. If using 127 levels you will
//need to change the start Character to some higher ascii value.
matrixPort.write(myFrame); // the frame data
}
}
So next part for me is making it split the output into sections so I can run a modular matrix.
But this does run my 16x16 RGB matrix just as is. Hope this makes sense to people.