我正在开发一个项目,一个名为“远程桌面控件”的客户端 - 服务器应用程序。我需要做的是拍摄客户端计算机的屏幕截图并将此屏幕捕获发送到服务器计算机。我可能需要每秒发送3到5张图像。但考虑到直接发送BufferedImage
对于该过程来说成本太高,我需要减小图像的大小。图像质量不必损失较少。
如何减小图像的字节大小?有什么建议吗?
答案 0 :(得分:6)
您可以使用GZIPInputStream及其插槽另一端的输出对应物,轻松地使用ZIP压缩它。
修改强>
另请注意,您可以创建 delta 图像进行传输,您可以使用“transpartent color”(魔术粉色#FF00FF)来表示屏幕的该部分未进行任何更改。另一方面,您可以在最后一个上绘制新图像,而忽略这些神奇的像素。
请注意,如果图片已包含此颜色,您可以将实际粉红色像素更改为#FF00FE。这是不可能的。
另一种选择是为每个图像传输 1位掩码(在将无变化像素绘制成任意颜色之后。为此,您可以更改主要用于颜色的颜色。图片产生最佳压缩比(最佳霍夫曼编码)。
答案 1 :(得分:4)
Vbence使用GZIPInputStream
的解决方案是一个很好的建议。在大多数商业软件(Windows远程桌面,VNC等)中完成此操作的方式是仅发送对屏幕缓冲区的更改。因此,您可以在服务器上保留客户“看到”的副本,并在每次连续捕获时计算屏幕区域的不同。然后,您只将这些屏幕区域连同它们的左上角,宽度,高度一起发送到客户端。并仅使用这些新区域更新客户端“视图”的服务器副本。
这将大大减少您使用的网络数据量,而我一直在输入此答案,每次击键时只有400左右像素(20x20)正在变化。这在1920x1080的屏幕上只是屏幕的1 / 10,000,所以显然值得思考。
唯一昂贵的部分是如何计算一帧与下一帧之间的“差异”。有很多库可以便宜地做到这一点,其中大多数是非常数学的(离散余弦变换类型的东西,在我脑海中),但它可以相对便宜地完成。
答案 2 :(得分:3)
答案 3 :(得分:2)
一种方法是使用ImageIO API
ImageIO.write(buffimg, "jpg", new File("buffimg.jpg"));
关于质量和其他参数 - 我不确定,但它应该是可能的,只是深入挖掘。