Skip to content

Instantly share code, notes, and snippets.

@rossanag
Forked from daan/jpeg.pde
Created July 11, 2016 21:35
Show Gist options
  • Select an option

  • Save rossanag/980ef5a847261ff87946f51ec67934e4 to your computer and use it in GitHub Desktop.

Select an option

Save rossanag/980ef5a847261ff87946f51ec67934e4 to your computer and use it in GitHub Desktop.
Super simple streaming video (mjpeg) in processing over an oscP5 tcp link.
/*
a simple jpeg encoder / decoder class
based on java standard libraries.
USAGE:
byte[] b = compressJpg(img,0.5);
PImage imgCompressed = decompressImage(b);
0.0 100% compression
1.0 0% compression
*/
import java.awt.image.BufferedImage;
import javax.imageio.plugins.jpeg.*;
import javax.imageio.*;
import javax.imageio.stream.*;
import java.util.Iterator;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.awt.image.BufferedImage;
byte[] compressJpg(PImage img, float compressionQuality)
{
byte[] compressed;
JPEGImageWriteParam jpegParams = new JPEGImageWriteParam(null);
jpegParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
jpegParams.setCompressionQuality(1f);
// copy image into a buffered image
BufferedImage out = new BufferedImage(img.width, img.height, BufferedImage.TYPE_INT_RGB);
for (int i=0; i<img.pixels.length; i++) {
out.setRGB(i % img.width, i/img.width, img.pixels[i]);
}
try {
// prepare a byte array stream to receive the jpg data
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
ImageOutputStream buffer2 = ImageIO.createImageOutputStream(buffer);
Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpeg");
ImageWriter writer = iter.next();
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(compressionQuality);
writer.setOutput(buffer2);
writer.write(null, new IIOImage(out,null,null),iwp);
writer.dispose();
buffer.flush();
byte[] bytesOut = buffer.toByteArray();
buffer.close();
return bytesOut;
}
catch (Exception e) {
System.out.println(e);
}
return null;
}
/*
i suppose this should work with any image
*/
PImage decompressImage(byte[] compressedImage) {
try {
// make a buffered image.
ByteArrayInputStream bufferIn = new ByteArrayInputStream(compressedImage);
BufferedImage in = ImageIO.read(bufferIn);
// prepare a processing image
PImage imageOut = new PImage( in.getWidth(null), in.getHeight(null));
imageOut.loadPixels();
// copy pixels
for (int x=0; x< in.getWidth(null); x++ ) {
for (int y=0; y< in.getHeight(null); y++ ) {
int rgb = in.getRGB(x, y);
imageOut.pixels[y*in.getWidth(null)+x] = rgb;
}
}
return imageOut;
}
catch (Exception e) {
System.out.println(e);
}
return null;
}
/*
streaming video between two processing sketches.
* no audio
* mjpeg ( frame by frame compression )
* over a tcp link ( osc )
* use the jpeg sketch for encoding/decoding
*/
import oscP5.*;
import netP5.*;
OscP5 client;
PImage imgIn;
void oscEvent(OscMessage msg) {
if( ! msg.checkAddrPattern("/video") ) return;
if( ! msg.checkTypetag("b") ) return;
byte[] b = msg.get(0).bytesValue();
// uncompress
imgIn = decompressImage(b);
}
void setup() {
size(320, 240);
client = new OscP5(this, "127.0.0.1", 12000, OscP5.TCP);
// client sends a message to connect to the server.
client.send("/new", new Object[] {new Integer(1)});
}
void draw() {
if (imgIn == null) return;
image(imgIn, 0, 0);
}
/*
streaming video between two processing sketches.
* no audio
* mjpeg ( frame by frame compression )
* over a tcp link ( osc )
* use the jpeg sketch for encoding/decoding
*/
import processing.video.*;
import oscP5.*;
import netP5.*;
OscP5 server;
Capture cam;
PImage imgOut;
void sendFrame(PImage img) {
TcpServer s = server.tcpServer();
if( s == null ) return; // should not happen
if( s.size() == 0) return; // no connected clients
// we send the frame to the first client only
TcpClient c = s.getClients()[0];
byte[] bimg = compressJpg(img, 0.7);
OscMessage msg= new OscMessage("/video");
msg.add(bimg);
server.send(msg, c);
}
/*
void oscEvent(OscMessage msg) {
println("received package");
}
*/
void setup() {
size(320, 240);
server = new OscP5(this, 12000, OscP5.TCP);
cam = new Capture(this, 320, 240);
cam.start();
}
void draw() {
if (cam.available() == true) {
cam.read();
imgOut = cam.copy();
sendFrame(imgOut);
}
if(imgOut == null) return;
image(imgOut, 0, 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment