Hi!
I’m working on a project that involves two PCs that simultaneously share and exchange the webcam source and send it, modified, to the other PC.
The script I’m relying on I found at https://github.com/torb-xyz/processing-experiments, merging CamNetClient, CamNetServer and JPEGEncode.
With some scripts it seems to work. Instead, in the script below it gives me the following error:
ClassCastException: class sun.java2d.SunGraphics2D cannot be cast to class java.awt.image.BufferedImage (sun.java2d.SunGraphics2D and java.awt.image.BufferedImage are in module java.desktop of loader 'bootstrap')
Here is the script:
SCRIPT
import processing.net.*;
import processing.video.*;
Client client;
Capture cam;
JPGEncoder jpg;
int state=0;
float scale=1.0;
PGraphics img;
Server server;
JPGEncoder jpg1;
PImage img1;
final int TIMEOUT_MILLI = 1 * 3000;
void setup() {
noCursor();
imageMode(CENTER);
size(1920,1080);
background(255);
img=createGraphics(640, 480);
jpg = new JPGEncoder();
jpg1 = new JPGEncoder();
// Start a server at port 5204
server = new Server(this, 5204);
img1 = createImage(100, 100, RGB);
println("Starting server");
cam = new Capture(this, Capture.list()[0]);
cam.start();
String server = "127.0.0.1";
client = new Client(this, server, 5203);
println("Starting client");
}
void draw() {
checkForIncomingImage();
image(img1, 1100, 100);
if (cam.available()) {
println("Cam available. Going to read");
cam.read();
try {
println("Getting image to memory");
background(0);
img.beginDraw();
img.image(cam,0,0);
img.endDraw();
img.loadPixels();
for (int x = 0; x < img.width; x++) {
for (int y = 0; y < img.height; y++) {
int loc = x+y*img.width;
float r = red(img.pixels[loc]);
float g = green(img.pixels[loc]);
float b = blue(img.pixels[loc]);
float d = dist(mouseX, mouseY, x, y);
float factor = map(d, 0, 200, 2, 0);
img.pixels[loc] = color(r*factor, g*factor, b*factor);
}
}
img.updatePixels();
translate(width/2,height/2);
scale(scale);
image(img,160,100);
println("Encoding");
byte[] jpgBytes = jpg.encode(img, 0.1F); //img
println("Writing file length to server: " + jpgBytes.length);
// Taken from: https://processing.org/discourse/beta/num_1192330628.html
client.write(jpgBytes.length / 256);
client.write(jpgBytes.length % 256);
println("Writing jpg bytes to server");
client.write(jpgBytes);
} catch (IOException e) {
// Ignore failure to encode
println("IOException");
}
}
}
void mousePressed(){
state=(state+1)%2; //Change state to either 0 or 1
scale= state==0 ? 1.0 : 3.0;
surface.setTitle("State:"+state+" scale:"+scale);
}
void checkForIncomingImage() {
Client nextClient = server.available();
if (nextClient != null && nextClient.available() >= 2) {
println("More than two bytes available. Trying to get length.");
// Taken from: https://processing.org/discourse/beta/num_1192330628.html
int imageByteLength = nextClient.read()*256 + nextClient.read();
println("Length is " + imageByteLength + ". Waiting for whole image.");
int startMilli = millis();
while (true) {
// Wait for the image...
// Abort if timeout has run out
if ((millis() - startMilli) > TIMEOUT_MILLI) {
println("Timeout.");
nextClient.clear();
break;
}
// Load it if finished
if (nextClient.available() >= imageByteLength) {
println("Enough in buffer, reading in...");
byte[] jpgBytes = new byte[imageByteLength];
nextClient.readBytes(jpgBytes);
nextClient.clear();
try {
img1 = jpg.decode(jpgBytes);
}
catch (IOException e) {
println("IOException in reading jpgbytes");
}
catch (NullPointerException e) {
println("NullPointerException in reading jpgbytes");
}
catch (ArrayIndexOutOfBoundsException e) {
println("ArrayIndexOutOfBoundsException in reading jpgbytes");
}
finally {
break;
}
}
}
}
}
JPGEncoder SCRIPT:
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.ImageWriteParam;
import javax.imageio.stream.MemoryCacheImageOutputStream;
import javax.imageio.IIOImage;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
public class JPGEncoder {
byte[] encode(PImage img, float compression) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next();
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(compression);
// ImageIO.write((BufferedImage) img.getNative(), "jpg", baos);
writer.setOutput(new MemoryCacheImageOutputStream(baos));
writer.write(null, new IIOImage((BufferedImage) img.getNative(), null, null), param);
return baos.toByteArray();
}
byte[] encode(PImage img) throws IOException {
return encode(img, 0.5F);
}
PImage decode(byte[] imgbytes) throws IOException, NullPointerException {
BufferedImage imgbuf = ImageIO.read(new ByteArrayInputStream(imgbytes));
PImage img = new PImage(imgbuf.getWidth(), imgbuf.getHeight(), RGB);
imgbuf.getRGB(0, 0, img.width, img.height, img.pixels, 0, img.width);
img.updatePixels();
return img;
}
}
Could you give me some suggestions on how to solve the error?
Thanks in advance