java-关于ImageIO.write(image, "JPEG", out);

dingshi0375 2017-01-16 02:24:09
package remoteclient;

import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;

import javax.imageio.ImageIO;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/*
* 发送客户端截图
*/
class ScreenSpyer extends Thread
{

Socket socket = null;
Robot robot = null; // Used to capture screen
Rectangle rectangle = null; // Used to represent screen dimensions
boolean continueLoop = true; // Used to exit the program
OutputStream out=null;
ObjectOutputStream oos = null; //对象输出流
JPEGImageEncoder encoder ;
public ScreenSpyer(Socket socket, Robot robot, Rectangle rect){
this.socket = socket;
this.robot = robot;
rectangle = rect;
start();
}

public void run()
{

try
{
socket.setSendBufferSize(1024);
//实例化对象
oos = new ObjectOutputStream(socket.getOutputStream());
out=socket.getOutputStream();
encoder=JPEGCodec.createJPEGEncoder(out);
// 发生客户端屏幕尺寸以计算鼠标所在位置
oos.writeObject(rectangle);
}
catch (IOException ex)
{
ex.printStackTrace();
}

while (continueLoop)
{
//截取客户端屏幕
BufferedImage image = robot.createScreenCapture(rectangle);
// 发生客户端截图到服务器
try
{
System.out.println("发送截图之前......");
ImageIO.write(image, "JPEG", out);
System.out.println("发送截图之后......");
}
catch (IOException ex)
{
ex.printStackTrace();
}

//等待0.1s减小网络阻塞
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}

}

}


代码如上,我自己写的一个远程桌面监控,上面的是客户端发送桌面屏幕给服务器的程序。
由于robot截图的屏幕图象是以位图格式获得的,直接传输会造成比较大的延时,为了提高远程控制的实时性,需要对获取的屏幕图象数据进行压缩后再传输,这里我用ImageIO.write(image, "JPEG", out);进行转换成jpeg格式图像,一传输到服务器,服务器立即就解析出jpeg图像格式了,但是有个很严重的问题!:

ImageIO.write(image, "JPEG", out);
这句代码居然耗时30s左右!找不到问题,求助!!
...全文
8523 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_42874496 2020-03-10
  • 打赏
  • 举报
回复
dingshi0375 2017-01-18
  • 打赏
  • 举报
回复
引用 8 楼 moguobiao 的回复:
出错可能是因为写得太快太多,可以试试增加SendBufferSize:
socket.setSendBufferSize(1024);

找到问题了,我在客户端发生图片之前加了这句代码,reading encoded JPEG Stream 这个错误就没了,能不断传送图片,依然用的是encoder.encode(image),但是服务端指令传不过来,好像被卡死的样子

dingshi0375 2017-01-18
  • 打赏
  • 举报
回复
引用 9 楼 dingshi0375 的回复:
[quote=引用 8 楼 moguobiao 的回复:] 出错可能是因为写得太快太多,可以试试增加SendBufferSize: socket.setSendBufferSize(1024);
有的这个我有写了。 我现在想是不是这个问题, 我客户端图片通过socket.getOutputStream输出到服务器,服务器的鼠标指令通过socket.getOutputStream输出到客户端,这样会有什么问题吗!我感觉问题在这![/quote] 客户端的指令接收socket.getInputStream可能接收客户端的图片输出的socket.getOutputStream和服务器指令输出的socket.getOutputStream
dingshi0375 2017-01-18
  • 打赏
  • 举报
回复
引用 8 楼 moguobiao 的回复:
出错可能是因为写得太快太多,可以试试增加SendBufferSize:
socket.setSendBufferSize(1024);


有的这个我有写了。
我现在想是不是这个问题,
我客户端图片通过socket.getOutputStream输出到服务器,服务器的鼠标指令通过socket.getOutputStream输出到客户端,这样会有什么问题吗!我感觉问题在这!
moguobiao 2017-01-18
  • 打赏
  • 举报
回复
出错可能是因为写得太快太多,可以试试增加SendBufferSize: socket.setSendBufferSize(1024);
dingshi0375 2017-01-17
  • 打赏
  • 举报
回复
引用 4 楼 bcsflilong 的回复:
[quote=引用 楼主 dingshi0375 的回复:]
package remoteclient;

import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;

import javax.imageio.ImageIO;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/*
 * 发送客户端截图
 */
class ScreenSpyer extends Thread
{

	Socket		socket			= null;
	Robot		robot			= null; // Used to capture screen
	Rectangle	rectangle		= null; // Used to represent screen dimensions
	boolean		continueLoop	= true; // Used to exit the program
	OutputStream out=null;
	ObjectOutputStream oos = null; //对象输出流
	JPEGImageEncoder encoder ;
	public ScreenSpyer(Socket socket, Robot robot, Rectangle rect){
		this.socket = socket;
		this.robot = robot;
		rectangle = rect;
		start();
	}

	public void run()
	{

		try
		{
			socket.setSendBufferSize(1024);
			//实例化对象
			oos = new ObjectOutputStream(socket.getOutputStream());
			out=socket.getOutputStream();
			encoder=JPEGCodec.createJPEGEncoder(out);
			// 发生客户端屏幕尺寸以计算鼠标所在位置
			oos.writeObject(rectangle);
		}
		catch (IOException ex)
		{
			ex.printStackTrace();
		}

		while (continueLoop)
		{		
			//截取客户端屏幕
			BufferedImage image = robot.createScreenCapture(rectangle);
			// 发生客户端截图到服务器
			try
			{
				System.out.println("发送截图之前......");
				ImageIO.write(image, "JPEG", out);
				System.out.println("发送截图之后......");
			}
			catch (IOException ex)
			{
				ex.printStackTrace();
			}

			//等待0.1s减小网络阻塞 
			try
			{
				Thread.sleep(100);
			}
			catch (InterruptedException e)
			{
				e.printStackTrace();
			}
		}

	}

}
代码如上,我自己写的一个远程桌面监控,上面的是客户端发送桌面屏幕给服务器的程序。 由于robot截图的屏幕图象是以位图格式获得的,直接传输会造成比较大的延时,为了提高远程控制的实时性,需要对获取的屏幕图象数据进行压缩后再传输,这里我用ImageIO.write(image, "JPEG", out);进行转换成jpeg格式图像,一传输到服务器,服务器立即就解析出jpeg图像格式了,但是有个很严重的问题!:
ImageIO.write(image, "JPEG", out);
这句代码居然耗时30s左右!找不到问题,求助!!
耗时多 是不是因为你一些数据流的开启和关闭没有控制好[/quote] 是的,后来我测试,连接上之后,服务器鼠标不动(服务器就不向客户端传输指令),图片延时将近50s。当连接上后,我服务器鼠标不断移动(服务器向客户端不断传输鼠标位置动作信息),延时居然缩小到了5s左右!但是现在还没找到问题。
bcsflilong 2017-01-17
  • 打赏
  • 举报
回复
引用 楼主 dingshi0375 的回复:
package remoteclient;

import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;

import javax.imageio.ImageIO;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/*
 * 发送客户端截图
 */
class ScreenSpyer extends Thread
{

	Socket		socket			= null;
	Robot		robot			= null; // Used to capture screen
	Rectangle	rectangle		= null; // Used to represent screen dimensions
	boolean		continueLoop	= true; // Used to exit the program
	OutputStream out=null;
	ObjectOutputStream oos = null; //对象输出流
	JPEGImageEncoder encoder ;
	public ScreenSpyer(Socket socket, Robot robot, Rectangle rect){
		this.socket = socket;
		this.robot = robot;
		rectangle = rect;
		start();
	}

	public void run()
	{

		try
		{
			socket.setSendBufferSize(1024);
			//实例化对象
			oos = new ObjectOutputStream(socket.getOutputStream());
			out=socket.getOutputStream();
			encoder=JPEGCodec.createJPEGEncoder(out);
			// 发生客户端屏幕尺寸以计算鼠标所在位置
			oos.writeObject(rectangle);
		}
		catch (IOException ex)
		{
			ex.printStackTrace();
		}

		while (continueLoop)
		{		
			//截取客户端屏幕
			BufferedImage image = robot.createScreenCapture(rectangle);
			// 发生客户端截图到服务器
			try
			{
				System.out.println("发送截图之前......");
				ImageIO.write(image, "JPEG", out);
				System.out.println("发送截图之后......");
			}
			catch (IOException ex)
			{
				ex.printStackTrace();
			}

			//等待0.1s减小网络阻塞 
			try
			{
				Thread.sleep(100);
			}
			catch (InterruptedException e)
			{
				e.printStackTrace();
			}
		}

	}

}
代码如上,我自己写的一个远程桌面监控,上面的是客户端发送桌面屏幕给服务器的程序。 由于robot截图的屏幕图象是以位图格式获得的,直接传输会造成比较大的延时,为了提高远程控制的实时性,需要对获取的屏幕图象数据进行压缩后再传输,这里我用ImageIO.write(image, "JPEG", out);进行转换成jpeg格式图像,一传输到服务器,服务器立即就解析出jpeg图像格式了,但是有个很严重的问题!:
ImageIO.write(image, "JPEG", out);
这句代码居然耗时30s左右!找不到问题,求助!!
耗时多 是不是因为你一些数据流的开启和关闭没有控制好
dingshi0375 2017-01-17
  • 打赏
  • 举报
回复
顶一下求大神
dingshi0375 2017-01-17
  • 打赏
  • 举报
回复
引用 6 楼 moguobiao 的回复:
By default,ImageIO 用到cache。试试用setUseCache(false)。可以参考javadoc:
http://atetric.com/atetric/javadoc/openjdk/jdk/8u92/javax/imageio/ImageIO.html#setUseCache-boolean-


大神啊!加上这句后传输速率飞快,但是传输10秒后系统奔了
moguobiao 2017-01-17
  • 打赏
  • 举报
回复
By default,ImageIO 用到cache。试试用setUseCache(false)。可以参考javadoc: http://atetric.com/atetric/javadoc/openjdk/jdk/8u92/javax/imageio/ImageIO.html#setUseCache-boolean-
dingshi0375 2017-01-16
  • 打赏
  • 举报
回复
引用 1 楼 dingshi0375 的回复:
当我把
ImageIO.write(image, "JPEG", out);
换成
encoder.encode(image);
之后 报错: 为什么?求大神
当换成encoder.encode(image);之后,服务器屏幕和客户端屏幕几乎就是同步的(客户端截图基本瞬时就传到服务器端,服务器端也马上就显示在屏幕上)
dingshi0375 2017-01-16
  • 打赏
  • 举报
回复
当我把
ImageIO.write(image, "JPEG", out);

换成
encoder.encode(image);
之后
报错:
为什么?求大神

51,396

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧