Java でネットワーク経由で Image オブジェクトを送信したいと考えています。
このエラーが発生します。
java.io.WriteAbortedException: 書き込みが中止されました。java.io.NotSerializableException: sun.awt.image.OffScreenImage
Java Image オブジェクトは Serializable を実装していません。これを回避する方法はありますか?
すでに画像のサブクラスを作成して実装しようとしましたが、 createImage メソッドを使用するとエラーが発生しました。助けてくれてありがとう。
編集*
ここにコードがありますが、ちょっとたくさんあります。プログラムのアイデアは、絵のゲームであることです。誰かが基本的なツールを使用して描画でき、ネットワーク経由で送信され、他のクライアントの画面にその画像が描画されます。
これは、ユーザーが線ツールを使用して描画する基本的な描画領域です。マウスを放すと、Image オブジェクトをサーバーに送信しようとします。
class PadDraw extends JComponent {
Image image;
Graphics2D graphics2D;
int currentX, currentY, oldX, oldY;
int lineSize = 1;
public PadDraw() {
setDoubleBuffered(false);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
oldX = e.getX();
oldY = e.getY();
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
currentX = e.getX();
currentY = e.getY();
//graphics2D.drawLine(oldX, oldY, currentX, currentY); //this is where it does the drawing
//It seems to draw a line between the old coordinate point and the new coordinate point rather than drawing it as points
//Test to see if I can get a drawoval to work rather than a line
//graphics2D.fillOval(currentX-1, currentY-1, 2, 2);
//if this works it should draw an oval at the cursor position rather than drawing a line
//technically it works, but without a line it causes gaps
//I may have found it. Testing the setStroke method
graphics2D.setStroke(new BasicStroke(lineSize));
graphics2D.drawLine(oldX, oldY, currentX, currentY);
repaint();
oldX = currentX;
oldY = currentY;
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
try {
clientOutputStream.writeObject(image);
} catch (IOException ex) {
Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
@Override
public void paintComponent(Graphics g) {
if (image == null) {
image = (Image) createImage(getSize().width, getSize().height);
graphics2D = (Graphics2D) image.getGraphics();
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
clear();
}
g.drawImage(image, 0, 0, null);
}
public void updateImage(Image image){
this.image = image;
repaint();
}
public void clear() {
graphics2D.setPaint(Color.white);
graphics2D.fillRect(0, 0, getSize().width, getSize().height);
//graphics2D.setPaint(Color.BLACK);
lineSize = 1;
repaint();
}
public void fill(){
Color c = findColor();
graphics2D.setPaint(c);
graphics2D.fillRect(0, 0, getSize().width, getSize().height);
repaint();
}
public void changeColor(Color theColor) {
graphics2D.setPaint(theColor);
repaint();
}
public Color findColor() {
return graphics2D.getColor();
}
public void changeSize(int size) {
lineSize = size;
}
}
これは、サーバー上のイメージのスレッド化されたクラスです。
private static class Handler2 extends Thread {
private Socket socket1;
private ObjectInputStream serverInputStream;
private ObjectOutputStream serverOutputStream;
public Handler2(Socket sock1) {
socket1 = sock1;
}
@Override
public void run() {
Image image = null;
try {
serverInputStream = new ObjectInputStream(socket1.getInputStream());
serverOutputStream = new ObjectOutputStream(socket1.getOutputStream());
oos.add(serverOutputStream);
while (true) {
image = (Image)serverInputStream.readObject();
for (ObjectOutputStream ooss : oos) {
ooss.writeObject(image);
}
}
} catch (IOException e) {
System.out.println(e);
} catch (ClassNotFoundException ex) {
Logger.getLogger(ChatServer.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if (serverOutputStream != null) {
oos.remove(serverOutputStream);
}
try {
socket1.close();
} catch (IOException e) {
System.out.println(e);
}
}
}
}
クライアントに戻ると、サーバーから画像を取得する方法があります。
public void run2() throws IOException, ClassNotFoundException, InterruptedException {
// Make connection and initialize streams
serverAddress = getServerAddress();
Socket socket2 = new Socket(serverAddress, 9999);
//String theIP = getIP();
//Socket socket2 = new Socket(theIP, 9999);
// Process all messages from server, according to the protocol.
clientOutputStream = new ObjectOutputStream(socket2.getOutputStream());
clientInputStream = new ObjectInputStream(socket2.getInputStream());
while (true) {
Image ni = (Image)clientInputStream.readObject();
drawPad.updateImage(ni);
}
}
私は自分のコードがちょっと悪いことを知っています。個々のパーツをテストするために多くのことを考えます。ネットワークコードと同じ料金です。それはうまくいくはずです。私が信じている唯一の問題は、シリアライズできないことです。