Last active
September 27, 2020 04:57
-
-
Save daan/8ff33a92ed4572fd953151de3181591e to your computer and use it in GitHub Desktop.
Super simple streaming video (mjpeg) in processing over an oscP5 tcp link.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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
I tried running this but I am getting a “No library found for com.sun.image.codec.jpeg”. Searching for an answer, I found this StackOverflow thread discussing the use of "sun" classes: http://stackoverflow.com/questions/1906673/import-com-sun-image-codec-jpeg