2012-08-10 49 views
2

我正在制作一个程序,将客户端屏幕发送到服务器并显示它,但速度非常慢。一帧需要2-3秒,上传/下载速度不成问题。有什么我做错了/我可以改变以加快速度?Java ImageIO非常慢

服务器:

import java.awt.BorderLayout; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.util.zip.GZIPInputStream; 

import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 

public class Server { 

    public static void main(String[] args) { 
     try { 
      JPanel panel = new JPanel(); 
      panel.setLayout(new BorderLayout()); 

      JLabel label = new JLabel(); 
      label.setSize(800, 600); 
      label.setVisible(true); 

      JScrollPane scroll = new JScrollPane(); 
      scroll.getViewport().add(label); 
      panel.add(scroll, BorderLayout.CENTER); 

      JFrame frame = new JFrame(); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.getContentPane().add(panel); 
      frame.setSize(800, 600); 
      frame.setVisible(true); 

      ServerSocket serverSocket = new ServerSocket(25565); 
      Socket socket = serverSocket.accept(); 
      GZIPInputStream in = new GZIPInputStream(socket.getInputStream()); 
      BufferedImage image = null; 
      while(socket.isConnected()) { 
       image = ImageIO.read(in); 
       if(image != null) { 
        label.setIcon(new ImageIcon(image)); 
        label.repaint(); 

       } 
      } 
      in.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

客户:

import java.awt.AWTException; 
import java.awt.Rectangle; 
import java.awt.Robot; 
import java.awt.Toolkit; 
import java.io.IOException; 
import java.net.Socket; 
import java.util.zip.GZIPOutputStream; 

import javax.imageio.ImageIO; 

public class Client { 

    public static void main(String[] args) { 
     try { 
      Robot robot = new Robot(); 
      Toolkit toolkit = Toolkit.getDefaultToolkit(); 
      Rectangle screen = new Rectangle((int) toolkit.getScreenSize().getWidth(), (int) toolkit.getScreenSize().getHeight()); 
      Socket socket = new Socket("127.0.0.1", 25565); 
      GZIPOutputStream out = new GZIPOutputStream(socket.getOutputStream()); 

      while(socket.isConnected()) { 
       ImageIO.write(robot.createScreenCapture(screen), "png", out); 
      } 
      out.close(); 
     } catch (AWTException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

你尝试过什么到目前为止找出性能瓶颈?你有没有做任何分析? – cyroxx 2012-08-10 23:47:33

+0

看这里:http://stackoverflow.com/questions/2293556/looking-for-a-faster-alternative-to-imageio或在这里:http://stackoverflow.com/questions/7726583/java-imageio-write-占用达6秒 – paulsm4 2012-08-11 00:01:06

+0

我很确定它是ImageIO,因为我记得当我检查哪种图像格式最好时,其中一些图像格式最多需要7秒才能写入磁盘。 – user1007883 2012-08-11 00:02:12

回答

3

如果您发送的图像作为png的GZIPStream可能是一个坏主意。由于png已经具有良好的压缩率,因此您不会获得显着的压缩增益。根据图像的种类,您还可以考虑使用jpeg来实现更好的压缩。

不过,也许最重要的是用BufferedOuputStream包装输出流:

BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream()); 

你可以做同样的输入流。

+0

PNG实际上使用zip压缩,并且使用GZIPInput/OutputStream会让事情变得更慢(并且最有可能增加数据开销而不是压缩)。 – haraldK 2013-06-03 14:08:14

2

你的问题自相矛盾。

一方面你问关于通过套接字发送图像。另一方面,你说“一帧需要2-3秒,上传/下载速度不是问题。”

我建议您尝试配置您的应用程序以确定图像捕获,图像转换,图像压缩或套接字I/O中是否存在瓶颈。其中任何一个都是合理的解释,而猜测不是识别真实的策略。

(如果您已经知道瓶颈在哪里......请不要混淆问题的范围,例如,如果您已经在知道问题出现在图像中如果你不知道知道这个,那么不要给我们提供潜在的错误信息......比如“上传/下载速度不对一个问题“。)

0

我相信所有给出的答案都不能解决问题。我怀疑,问题是不是的网络连接,而是ImageIO.read(InputStream)方法。该版本的方法只是非常慢。如果您尝试从本地驱动器加载它作为流(而ImageIO.read(文件)执行得很好),也会发生2-3秒。

我解决了这个问题:

ImageIO.setUseCache(false); 

此处了解详情: Byte array to buffered image conversion slow