Как ускорить частоту кадров удаленного просмотра? - PullRequest
0 голосов
/ 08 ноября 2018

Итак, я создал приложение, состоящее из двух частей: клиента и сервера. Клиент делает снимок экрана, преобразует его в байтовый массив, отправляет его на сервер, а затем ожидает ответа, чтобы повторить все это. Сервер берет байтовый массив, превращает его в снимок экрана, отображает снимок экрана и затем сообщает клиенту, что все готово.

Все работает прекрасно, но проблема в том, что для завершения всего процесса требуется около 200-350 мс, а это означает, что самое большее я получаю пять кадров в секунду. Это явно неудовлетворительно, и поэтому мне интересно, что я могу сделать, чтобы ускорить этот процесс. Есть ли более быстрый способ делать скриншоты? Имеет ли большое значение наличие монитора 1080x1920, а не меньшего разрешения? Является ли длительное время из-за того, что размер изображения должен соответствовать размеру коробки? и т.д ..

Вот клиент:

// Capture the image
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage capture = robot.createScreenCapture(screenRect);
// Convert the image to a byte array

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(capture, "jpg", baos);
byte[] bytes = baos.toByteArray();
// Send byte array over socket connection
Socket socket = new Socket("machine", 2282);
DataOutputStream outputData = new DataOutputStream(socket.getOutputStream());
DataInputStream inputData = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
outputData.write(bytes);
outputData.close();
// Wait for response
String incomingData = inputData.readUTF();
inputData.close();

if (incomingData.equals("1"))
    break;

и сервер:

long startTime = System.nanoTime();
// Get client and receive byte array
ServerSocket server = new ServerSocket(2282);
Socket socket = server.accept();
DataInputStream inputData = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
DataOutputStream outputData = new DataOutputStream(socket.getOutputStream());
// Read bytes to byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buffer[] = new byte[1024];
for (int s; (s = inputData.read(buffer)) != -1;) {
  baos.write(buffer, 0, s);
}
byte result[] = baos.toByteArray();
// Create bufferedImage from byte array
BufferedImage bufferedImage = null;
ByteArrayInputStream bais = new ByteArrayInputStream(result);
bufferedImage = ImageIO.read(bais);
// Update image box
imageBox.setBounds(10, 11, (frame.getWidth() - 40), (frame.getHeight()) - 50);
BufferedImage resizedImage = resize(bufferedImage, imageBox.getHeight(), imageBox.getWidth());
imageBox.setIcon(new ImageIcon(resizedImage));

outputData.writeUTF("1");
// Close everything
outputData.close();
server.close();
socket.close();
inputData.close();
baos.close();
bais.close();

long endTime = System.nanoTime();
long totalTime = (endTime - startTime) / 1000000;
System.out.println(totalTime);

А затем метод изменения размера:

public static BufferedImage resize(BufferedImage img, int height, int width) {
    Image image = img.getScaledInstance(width, height, Image.SCALE_SMOOTH);
    BufferedImage resized = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    Graphics2D graphics2d = resized.createGraphics();
    graphics2d.drawImage(image, 0, 0, null);
    graphics2d.dispose();
    return resized;
}

При этом сервер занимает около 20% ЦП (3,20 ГГц) и 40% ОЗУ (8 ГБ). Это не ограничивается этим, но обычно не превышает этого.

...