Java ImageIO非常慢

时间:2012-08-10 23:45:45

标签: java image screenshot javax.imageio

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

服务器:

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();
        }
    }
}

3 个答案:

答案 0 :(得分:4)

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

但最重要的可能是使用BufferedOuputStream包装输出流:

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

您可以在输入流中执行相同的操作。

答案 1 :(得分:2)

你的问题自相矛盾。

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

我建议您尝试对应用程序进行概要分析,以确定瓶颈是否在图像捕获,图像转换,图像压缩或套接字I / O中。其中任何一个都是似是而非的解释, guesswork 不是识别真实的好策略。

(如果您已经知道瓶颈在哪里......请不要通过在问题中包含其余步骤来混淆问题。例如,如果您已经知道该问题在图像转换中,甚至没有必要提到你是通过网络发送图像的。但如果你不知道这个,那么就不要给我们提供潜在的虚假信息......比如“上传/下载速度不是问题”。)

答案 2 :(得分:0)

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

我用以下方法解决了问题:

ImageIO.setUseCache(false);

更多信息: Byte array to buffered image conversion slow