3

クライアントの画面をサーバーに送信して表示するプログラムを作成していますが、非常に遅いです。1コマ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();
        }
    }
}
4

3 に答える 3

5

pngGZIPStreamとして画像を送信する場合は、おそらく悪い考えです。pngはすでに適切な圧縮率を備えているため、大幅な圧縮率の向上は達成できません。画像の種類によっては、jpegより良い圧縮を実現することも検討できます。

しかし、おそらく最も重要なのは、出力ストリームをBufferedOuputStreamでラップすることです。

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

入力ストリームでも同じことができます。

于 2012-08-11T02:42:34.640 に答える
2

与えられたすべての回答が問題に対処しているとは思いません。問題はネットワーク接続ではなく、 ImageIO.read(InputStream) メソッドにあると思われます。このバージョンのメソッドは、非常に遅いだけです。ローカルドライブからストリームとしてロードしようとすると、2〜3秒も発生します(ImageIO.read(File)は問題なく実行されます)。

私は問題を解決しました:

ImageIO.setUseCache(false);

詳細はこちら: バイト配列からバッファリングされた画像への変換が遅い

于 2016-11-02T18:35:42.763 に答える
2

あなたの質問は矛盾しています。

一方では、ソケットを介して画像を送信することについて尋ねます。一方で、「1 フレームに 2 ~ 3 秒かかります。アップロード/ダウンロードの速度は問題ありません。」

アプリケーションのプロファイルを作成して、ボトルネックが画像のキャプチャ、画像の変換、画像の圧縮、またはソケット I/O にあるかどうかを判断することをお勧めします。これらのいずれももっともらしい説明であり、当て推量は本当の説明を特定するための優れた戦略ではありません.

(そして、ボトルネックがどこにあるかをすでに知っている場合は、質問に残りの手順を含めて問題を混乱させないでください。たとえば、問題が画像変換にあることがすでにわかっている場合は、ネットワークを介して画像を送信していることに言及することもできます.しかし、これがわからない場合は「アップロード/ダウンロードの速度は問題ではありません」など、誤っている可能性のある情報を提供しないでください.)

于 2012-08-11T02:52:47.120 に答える