3

我正在开发一个项目,一个名为“远程桌面控制”的客户端-服务器应用程序。我需要做的是截取客户端计算机的屏幕截图并将此屏幕截图发送到服务器计算机。我可能需要每秒发送 3 到 5 张图像。但是考虑到BufferedImage直接发送对于该过程来说成本太高,我需要减小图像的大小。图像质量不必损失较少。

如何减小图像的字节大小?有什么建议么?

4

4 回答 4

6

通过使用GZIPInputStream及其在套接字另一端的输出副本,您可以非常轻松地使用 ZIP 压缩它。

编辑:

另请注意,您可以创建用于传输的增量图像,例如,您可以使用“透明颜色”(神奇的粉红色#FF00FF)来指示屏幕的该部分没有进行任何更改。另一方面,您可以在最后一张上绘制新图像,忽略这些魔术像素。

请注意,如果图片已经包含此颜色,您可以将真正的粉红色像素更改为 #FF00FE。这是不明显的。

另一种选择是为每个图像传输一个1 位掩码(在将不变像素绘制为任意颜色之后。为此,您可以更改图片中主要使用的颜色以产生最佳压缩比(最佳霍夫曼编码)。

于 2012-08-08T08:09:06.493 回答
4

Vbence 使用 a 的解决方案GZIPInputStream是一个很好的建议。在大多数商业软件(Windows 远程桌面、VNC 等)中执行此操作的方式是仅发送对屏幕缓冲区的更改。因此,您在服务器上保留客户端“看到”的内容的副本,并且每次连续捕获时,您都会计算屏幕区域的不同之处。然后,您只需将这些屏幕区域连同它们的左上角坐标、宽度、高度一起发送给客户端。并仅使用这些新区域更新客户端“视图”的服务器副本。

这将大大减少您使用的网络数据量,虽然我一直在输入这个答案,但每次击键只会改变 400 左右像素(20x20)。这在 1920x1080 屏幕上只是屏幕的 1/10,000,因此显然值得考虑。

唯一昂贵的部分是如何计算一帧和下一帧之间的“差异”。有很多图书馆可以廉价地做到这一点,其中大多数都非常数学化(离散余弦变换类型的东西,在我的头脑中),但它可以相对便宜地完成。

于 2012-08-08T09:46:16.173 回答
3

有关如何以可控压缩/质量编码为 JPG 的信息,请参阅此线程。左侧的滑块用于控制级别。

最终,将图像直接编码为可以流式传输的视频编解码器会更好,但我对细节有点模糊。

于 2012-08-08T09:44:36.763 回答
2

一种方法是使用 ImageIO API

ImageIO.write(buffimg, "jpg", new File("buffimg.jpg"));  

至于质量和其他参数 - 我不确定,但应该是可能的,只是深入挖掘。

于 2012-08-08T08:12:00.627 回答