From d04b28e7d314313ffd6970a4a3fe562e2dcef294 Mon Sep 17 00:00:00 2001 From: Alexandre Rivaux Date: Tue, 24 Nov 2015 10:50:28 +0100 Subject: [PATCH] 20151124-1049-Installation - Quick R&D for capturing image through UDP or via ScreenCaptured Based on : http://shiffman.net/2010/11/13/streaming-video-with-udp-in-processing/ https://github.com/onformative/ScreenCapturer/issues/2 --- .../SimpleScreenCapturer/ScreenCapturer.pde | 24 +++++ .../SimpleScreenCapturer.pde | 13 +++ .../VideoReceiver/VideoReceiver.pde | 60 +++++++++++ .../VideoReceiverThread/ReceiverThread.pde | 96 ++++++++++++++++++ .../VideoReceiverThread.pde | 30 ++++++ .../VideoSender/VideoSender.pde | 99 +++++++++++++++++++ 6 files changed, 322 insertions(+) create mode 100644 installation/SimpleScreenCapturer/ScreenCapturer.pde create mode 100644 installation/SimpleScreenCapturer/SimpleScreenCapturer.pde create mode 100644 installation/image_streaming/image_streaming/VideoReceiver/VideoReceiver.pde create mode 100644 installation/image_streaming/image_streaming/VideoReceiverThread/ReceiverThread.pde create mode 100644 installation/image_streaming/image_streaming/VideoReceiverThread/VideoReceiverThread.pde create mode 100644 installation/image_streaming/image_streaming/VideoSender/VideoSender.pde diff --git a/installation/SimpleScreenCapturer/ScreenCapturer.pde b/installation/SimpleScreenCapturer/ScreenCapturer.pde new file mode 100644 index 0000000..6232e14 --- /dev/null +++ b/installation/SimpleScreenCapturer/ScreenCapturer.pde @@ -0,0 +1,24 @@ +import java.awt.Robot; +import java.awt.Rectangle; +import java.awt.AWTException; + +class SimpleScreenCapture { + + Robot robot; + + PImage screenshot; + + SimpleScreenCapture() { + try { + robot = new Robot(); + } + catch (AWTException e) { + println(e); + } + } + + PImage get() { + screenshot = new PImage(robot.createScreenCapture(new Rectangle(0, 0, width, height))); + return screenshot; + } +} \ No newline at end of file diff --git a/installation/SimpleScreenCapturer/SimpleScreenCapturer.pde b/installation/SimpleScreenCapturer/SimpleScreenCapturer.pde new file mode 100644 index 0000000..8340678 --- /dev/null +++ b/installation/SimpleScreenCapturer/SimpleScreenCapturer.pde @@ -0,0 +1,13 @@ +SimpleScreenCapture simpleScreenCapture; + +void setup() { +size(1920, 1080, P3D); +simpleScreenCapture = new SimpleScreenCapture(); + +} + +void draw() { + +image(simpleScreenCapture.get(), 0, 0, width, height); + +} \ No newline at end of file diff --git a/installation/image_streaming/image_streaming/VideoReceiver/VideoReceiver.pde b/installation/image_streaming/image_streaming/VideoReceiver/VideoReceiver.pde new file mode 100644 index 0000000..6a6924d --- /dev/null +++ b/installation/image_streaming/image_streaming/VideoReceiver/VideoReceiver.pde @@ -0,0 +1,60 @@ +import java.awt.image.*; +import javax.imageio.*; + + +// Port we are receiving. +int port = 9100; +DatagramSocket ds; +// A byte array to read into (max size of 65536, could be smaller) +byte[] buffer = new byte[65536]; + +PImage video; + +void setup() { + size(400,300); + try { + ds = new DatagramSocket(port); + } catch (SocketException e) { + e.printStackTrace(); + } + video = createImage(320,240,RGB); +} + + void draw() { + // checkForImage() is blocking, stay tuned for threaded example! + checkForImage(); + + // Draw the image + background(0); + imageMode(CENTER); + image(video,width/2,height/2); +} + +void checkForImage() { + DatagramPacket p = new DatagramPacket(buffer, buffer.length); + try { + ds.receive(p); + } catch (IOException e) { + e.printStackTrace(); + } + byte[] data = p.getData(); + + println("Received datagram with " + data.length + " bytes." ); + + // Read incoming data into a ByteArrayInputStream + ByteArrayInputStream bais = new ByteArrayInputStream( data ); + + // We need to unpack JPG and put it in the PImage video + video.loadPixels(); + try { + // Make a BufferedImage out of the incoming bytes + BufferedImage img = ImageIO.read(bais); + // Put the pixels into the video PImage + img.getRGB(0, 0, video.width, video.height, video.pixels, 0, video.width); + } catch (Exception e) { + e.printStackTrace(); + } + // Update the PImage pixels + video.updatePixels(); +} + diff --git a/installation/image_streaming/image_streaming/VideoReceiverThread/ReceiverThread.pde b/installation/image_streaming/image_streaming/VideoReceiverThread/ReceiverThread.pde new file mode 100644 index 0000000..623efb5 --- /dev/null +++ b/installation/image_streaming/image_streaming/VideoReceiverThread/ReceiverThread.pde @@ -0,0 +1,96 @@ +// Daniel Shiffman +// + +// A Thread using receiving UDP + +class ReceiverThread extends Thread { + + // Port we are receiving. + int port = 9100; + DatagramSocket ds; + // A byte array to read into (max size of 65536, could be smaller) + byte[] buffer = new byte[65536]; + + boolean running; // Is the thread running? Yes or no? + boolean available; // Are there new tweets available? + + // Start with something + PImage img; + + ReceiverThread (int w, int h) { + img = createImage(w,h,RGB); + running = false; + available = true; // We start with "loading . . " being available + + try { + ds = new DatagramSocket(port); + } catch (SocketException e) { + e.printStackTrace(); + } + } + + PImage getImage() { + // We set available equal to false now that we've gotten the data + available = false; + return img; + } + + boolean available() { + return available; + } + + // Overriding "start()" + void start () { + running = true; + super.start(); + } + + // We must implement run, this gets triggered by start() + void run () { + while (running) { + checkForImage(); + // New data is available! + available = true; + } + } + + void checkForImage() { + DatagramPacket p = new DatagramPacket(buffer, buffer.length); + try { + ds.receive(p); + } + catch (IOException e) { + e.printStackTrace(); + } + byte[] data = p.getData(); + + //println("Received datagram with " + data.length + " bytes." ); + + // Read incoming data into a ByteArrayInputStream + ByteArrayInputStream bais = new ByteArrayInputStream( data ); + + // We need to unpack JPG and put it in the PImage img + img.loadPixels(); + try { + // Make a BufferedImage out of the incoming bytes + BufferedImage bimg = ImageIO.read(bais); + // Put the pixels into the PImage + bimg.getRGB(0, 0, img.width, img.height, img.pixels, 0, img.width); + } + catch (Exception e) { + e.printStackTrace(); + } + // Update the PImage pixels + img.updatePixels(); + } + + + // Our method that quits the thread + void quit() { + System.out.println("Quitting."); + running = false; // Setting running to false ends the loop in run() + // In case the thread is waiting. . . + interrupt(); + } +} + diff --git a/installation/image_streaming/image_streaming/VideoReceiverThread/VideoReceiverThread.pde b/installation/image_streaming/image_streaming/VideoReceiverThread/VideoReceiverThread.pde new file mode 100644 index 0000000..4afc24e --- /dev/null +++ b/installation/image_streaming/image_streaming/VideoReceiverThread/VideoReceiverThread.pde @@ -0,0 +1,30 @@ +// Daniel Shiffman +// + +// A Thread using receiving UDP to receive images + +import java.awt.image.*; +import javax.imageio.*; +import java.net.*; +import java.io.*; + +PImage video; +ReceiverThread thread; + +void setup() { + size(400,300); + video = createImage(320,240,RGB); + thread = new ReceiverThread(video.width,video.height); + thread.start(); +} + + void draw() { + if (thread.available()) { + video = thread.getImage(); + } + + // Draw the image + background(0); + imageMode(CENTER); + image(video,width/2,height/2); +} \ No newline at end of file diff --git a/installation/image_streaming/image_streaming/VideoSender/VideoSender.pde b/installation/image_streaming/image_streaming/VideoSender/VideoSender.pde new file mode 100644 index 0000000..56fee94 --- /dev/null +++ b/installation/image_streaming/image_streaming/VideoSender/VideoSender.pde @@ -0,0 +1,99 @@ +import processing.video.*; + +import javax.imageio.*; +import java.awt.image.*; +import java.net.*; +import java.io.*; + +// This is the port we are sending to +int clientPort = 9100; +// This is our object that sends UDP out +DatagramSocket ds; +// Capture object +Capture cam; + +void setup() { + size(320, 240); + // Setting up the DatagramSocket, requires try/catch + try { + ds = new DatagramSocket(); + } + catch (SocketException e) { + e.printStackTrace(); + } + // Initialize Camera + String[] cameras = Capture.list(); + + if (cameras == null) { + println("Failed to retrieve the list of available cameras, will try the default..."); + cam = new Capture(this, 640, 480); + } + if (cameras.length == 0) { + println("There are no cameras available for capture."); + exit(); + } else { + println("Available cameras:"); + for (int i = 0; i < cameras.length; i++) { + println(i, cameras[i]); + } + + // The camera can be initialized directly using an element + // from the array returned by list(): + cam = new Capture(this, cameras[9]); + // Or, the settings can be defined based on the text in the list + //cam = new Capture(this, 640, 480, "Built-in iSight", 30); + + // Start capturing the images from the camera + cam.start(); + } + //cam = new Capture( this, width, height, 30); +} + +void captureEvent( Capture c ) { + c.read(); + // Whenever we get a new image, send it! + broadcast(c); +} + +void draw() { + image(cam, 0, 0, width, height); +} + + +// Function to broadcast a PImage over UDP +// Special thanks to: http://ubaa.net/shared/processing/udp/ +// (This example doesn't use the library, but you can!) +void broadcast(PImage img) { + + // We need a buffered image to do the JPG encoding + BufferedImage bimg = new BufferedImage( img.width, img.height, BufferedImage.TYPE_INT_RGB ); + + // Transfer pixels from localFrame to the BufferedImage + img.loadPixels(); + bimg.setRGB( 0, 0, img.width, img.height, img.pixels, 0, img.width); + + // Need these output streams to get image as bytes for UDP communication + ByteArrayOutputStream baStream = new ByteArrayOutputStream(); + BufferedOutputStream bos = new BufferedOutputStream(baStream); + + // Turn the BufferedImage into a JPG and put it in the BufferedOutputStream + // Requires try/catch + try { + ImageIO.write(bimg, "jpg", bos); + } + catch (IOException e) { + e.printStackTrace(); + } + + // Get the byte array, which we will send out via UDP! + byte[] packet = baStream.toByteArray(); + + // Send JPEG data as a datagram + println("Sending datagram with " + packet.length + " bytes"); + try { + ds.send(new DatagramPacket(packet, packet.length, InetAddress.getByName("localhost"), clientPort)); + } + catch (Exception e) { + e.printStackTrace(); + } +} \ No newline at end of file