2016-06-24 3 views
0

を介して送信、私は継続的にウェブカメラから画像を取得し、サーバーへのソケットを介してそれを送信するためにこのコードを記述します。Javaは私がsarxos <a href="http://webcam-capture.sarxos.pl/" rel="nofollow">http://webcam-capture.sarxos.pl/</a></p> <p>によって<code>Webcam capture API</code>を使用しているウェブカメラから画像を取得し、ソケット

クライアントコード

public static void main(String[] args) throws IOException 
{ 
    Socket socket = new Socket("127.0.0.1", 54339); 
    ObjectOutputStream sender = new ObjectOutputStream(socket.getOutputStream()); 
    Webcam wCam = Webcam.getDefault(); 
    wCam.setViewSize(WebcamResolution.VGA.getSize()); 
    wCam.open(); 
    while (true) 
    { 
     sender.writeObject(new ImageIcon(wCam.getImage())); 
    } 
} 

Serverコード

public static void main(String[] args) throws IOException 
{ 
    ServerSocket server = new ServerSocket(54339); 
    Socket socket = server.accept(); 

    ObjectInputStream rcv = new ObjectInputStream(socket.getInputStream()); 
    while (true) 
    { 
     rcv.readObject(); 
     System.out.println("receive"); 
    } 
} 

しかし、その後約2後 - 3分、私のクライアントは、メモリが不足し、それはあまりにも多くのRAMがかかるため立ち往生。

私はそれがあるため、この行new ImageIcon(wCam.getImage())のだと思うが、私はそれを修正する方法がわかりません。

私はsender.flush()を試みたが、それは基本的にObjectOutputStream.writeObject()

答えて

0

を仕事とObjectInputStream.readObject()それらが受信/送信されたオブジェクトへのhardreferencesのテーブルを保持していません。オブジェクトがObjectOutputStreamによって再送ときObjectInputStreamが以前に受信されたオブジェクトの参照に受信ハンドルを変換しながら、オブジェクトへのハンドルのみが送信されます。この機能は帯域幅とメモリ使用量を削減しますが、オブジェクトが定期的に再送信されるプログラムでのみ使用されます。 ObjectInputStream/ObjectOutputStreamこれらのオブジェクトをハード参照するため、Garbage Collectorはそれらを収集できず、最終的にこれらのオブジェクトはメモリリークになりました。これを避けるために

、JavaはObjectOutputStream.writeUnshared()ObjectInputStream.readUnshared()方法を提供していますが、これらの方法も知られているメモリは、その問題についての詳細はJDK-6525563 : Memory leak in ObjectOutputStreamをチェックし、問題をリークしています。

ですから、2つのオプションがあります。 ObjectInput/OutputStreamを使用して

  1. 利用read/writeUnshared()代わりのread/writeObject()ObjectOutputStreamによってリークしたメモリを解放するために、すべてたまにObjectOutputStreamreset()メソッドを呼び出して、
  2. は避けてください。このようにBufferedImageDataInput/OutputStreamと読み書きできます。

執筆:

try (DataOutputStream sender = new DataOutputStream(new BufferedOutputStream(new Socket("127.0.0.1", 54339).getOutputStream()))) //never use DataStreams without buffering, too slow 
{ 
    while (true) 
    { 
     BufferedImage frame = wCam.getImage(); //get frame from webcam 
     int frameWidth = frame.getWidth(); 
     int frameHeight = frame.getHeight(); 

     sender.writeInt(frameWidth); //write image with 
     sender.writeInt(frameHeight); //write image height 

     int[] pixelData = new int[frameWidth * frameHeight]; 
     frame.getRGB(0, 0, frameWidth, frameHeight, pixelData, 0, frameWidth); 

     for (int i = 0; i < pixelData.length; i++) 
     { 
      sender.writeInt(pixelData[i]); //write pixel data 
     } 
    } 
} 

読書:

try (DataInputStream rcv = new DataInputStream(new BufferedInputStream(socket.getInputStream()))) //never use DataStreams without buffering, too slow 
{ 

    while (true) 
    { 
     int frameWidth = rcv.readInt(); //read image with 
     int frameHeight = rcv.readInt(); //read image height 

     int[] pixelData = new int[frameWidth * frameHeight]; 
     for (int i = 0; i < pixelData.length; i++) 
     { 
      pixelData[i] = rcv.readInt(); //read pixel data 
     } 

     BufferedImage frame = new BufferedImage(frameWidth, frameHeight, BufferedImage.TYPE_INT_RGB); //create immage 
     frame.setRGB(0, 0, frameWidth, frameHeight, pixelData, 0, frameWidth); //set pixel data 

     //do whatever you want with frame 
    } 
} 

また、サーバー上で受信した画像を表示すると方法2の私の実装。

Server.java

public class Server 
{ 
    public static void main (String[] args) throws IOException, ClassNotFoundException 
    { 
     ServerSocket server = new ServerSocket(54339); 
     Socket socket = server.accept(); 

     JFrame jframe = new JFrame(); 
     jframe.setSize(800, 600); 
     jframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     jframe.setLayout(new BorderLayout()); 

     ImageDisplayPanel imageDisplayPanel = new ImageDisplayPanel(); 
     jframe.add(imageDisplayPanel, BorderLayout.CENTER); 

     jframe.setVisible(true); 

     try (DataInputStream rcv = new DataInputStream(new BufferedInputStream(socket.getInputStream()))) 
     { 

      while (true) 
      { 
       int frameWidth = rcv.readInt(); 
       int frameHeight = rcv.readInt(); 

       int[] pixelData = new int[frameWidth * frameHeight]; 

       for (int i = 0; i < pixelData.length; i++) 
       { 
        pixelData[i] = rcv.readInt(); 
       } 

       BufferedImage frame = new BufferedImage(frameWidth, frameHeight, BufferedImage.TYPE_INT_RGB); 
       frame.setRGB(0, 0, frameWidth, frameHeight, pixelData, 0, frameWidth); 

       imageDisplayPanel.setBackground(frame); 
      } 
     } 
    } 


    private static class ImageDisplayPanel extends JPanel 
    { 
     private static final Object BACKGROUND_LOCK = new Object(); 
     private BufferedImage background = null; 

     public ImageDisplayPanel() throws HeadlessException 
     { 
      this.setDoubleBuffered(true); //to avoid flicker 
     } 

     public void setBackground (Image newBackground) 
     { 
      synchronized (BACKGROUND_LOCK) 
      { 
       if (background == null) 
       { 
        background = new BufferedImage(newBackground.getWidth(null), newBackground.getHeight(null), BufferedImage.TYPE_INT_RGB); 
       } 
       else if (background.getWidth() != newBackground.getWidth(null) || background.getHeight() != newBackground.getHeight(null)) 
       { 
        background.flush();//flush old resources first 
        background = new BufferedImage(newBackground.getWidth(null), newBackground.getHeight(null), BufferedImage.TYPE_INT_RGB); 
       } 
       Graphics graphics = background.createGraphics(); 
       graphics.drawImage(newBackground, 0, 0, null); 
      } 
      repaint(); 
     } 

     @Override 
     public void paint (Graphics g) 
     { 
      super.paint(g); 
      synchronized (BACKGROUND_LOCK) 
      { 
       if (background != null) 
       { 
        g.drawImage(background, 0, 0, getWidth(), getHeight(), null); 
       } 
      } 
     } 
    } 
} 

Client.java

public class Client 
{ 
    public static void main (String[] args) throws IOException 
    { 
     Webcam wCam = null; 
     try (DataOutputStream sender = new DataOutputStream(new BufferedOutputStream(new Socket("127.0.0.1", 54339).getOutputStream()))) 
     { 

      wCam = Webcam.getDefault(); 
      wCam.setViewSize(WebcamResolution.VGA.getSize()); 
      wCam.open(); 
      while (true) 
      { 
       BufferedImage frame = wCam.getImage(); //get frame from webcam 

       int frameWidth = frame.getWidth(); 
       int frameHeight = frame.getHeight(); 

       sender.writeInt(frameWidth); 
       sender.writeInt(frameHeight); 

       int[] pixelData = new int[frameWidth * frameHeight]; 
       frame.getRGB(0, 0, frameWidth, frameHeight, pixelData, 0, frameWidth); 

       for (int i = 0; i < pixelData.length; i++) 
       { 
        sender.writeInt(pixelData[i]); 
       } 
      } 
     } finally 
     { 
      //release resources used by library 
      if (wCam != null) 
      { 
       wCam.close(); 
      } 
      Webcam.shutdown(); 
     } 

    } 
} 
関連する問題

 関連する問題