How to scale down the size and quality of an BufferedImage?

痞子三分冷 提交于 2019-12-12 14:26:01

问题


I'm working on a project, a client-server application named 'remote desktop control'. What I need to do is take a screen capture of the client computer and send this screen capture to the server computer. I would probably need to send 3 to 5 images per second. But considering that sending BufferedImage directly will be too costly for the process, I need to reduce the size of the images. The image quality need not to be loss less.

How can I reduce the byte size of the image? Any suggestions?


回答1:


You can compress it with ZIP very easily by using GZIPInputStream and its output counterpart on the other end of the socket.

Edit:

Also note that you can create delta images for transmission, you can use a "transpartent color" for example (magic pink #FF00FF) to indicate that no change was made on that part of the screen. On the other side you can draw the new image over the last one ignoring these magic pixels.

Note that if the picture already contains this color you can change the real pink pixels to #FF00FE for example. This is unnoticable.

An other option is to transmit a 1-bit mask with every image (after painting the no-change pixels to an arbitrary color. For this you can change the color which is mostly used in the picture to result in the best compression ratio (optimal huffman-coding).




回答2:


Vbence's solution of using a GZIPInputStream is a good suggestion. The way this is done in most commercial software - Windows Remote Desktop, VNC, etc. is that only changes to the screen-buffer are sent. So you keep a copy on the server of what the client 'sees', and with each consecutive capture you calculate what is different in terms of screen areas. Then you only send these screen areas to the client along with their top-left coords, width, height. And update the server copy of the client 'view' with just these new areas.

That will MASSIVELY reduce the amount of network data you use, while I have been typing this answer, only 400 or so pixels (20x20) are changing with each keystroke. This on a 1920x1080 screen is just 1/10,000th of the screen, so clearly worth thinking about.

The only expensive part is how you calculate the 'difference' between one frame and the next. There are plenty of libraries out there to do that cheaply, most of them very mathematical (discrete cosine transform type stuff, way over my head), but it can be done relatively cheaply.




回答3:


See this thread for how to encode to JPG with controllable compression/quality. The slider on the left is used to control the level.

Ultimately it would be better to encode the images directly to a video codec that can be streamed, but I am a little hazy on the details.




回答4:


One way would be to use ImageIO API

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

As for the quality and other parameters- I'm not sure, but it should be possible, just dig deeper.



来源:https://stackoverflow.com/questions/11860266/how-to-scale-down-the-size-and-quality-of-an-bufferedimage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!