我有BufferedImage
显示在JFrame
,我想要通过Socket(byte[] buffer)
收到的原始R,G,B数据定期刷新。动作序列应该是这样的:定期刷新BufferedImage
- 接收字节[1280 * 480]纯的RGB数据(每个部件的一个字节)的阵列 - >该部分通过字节数组工作无瑕疵
- 迭代和呼叫
BufferedImage.setRgb(x, y, RGB)
为每个像素
我没有接收和显示一帧的问题,但是当我执行步骤1和2的代码时,我会定期接收数据,但不会显示单个帧。我的猜测是,接收数据比显示图像要快得多,换句话说,我的接收图像被某种新图像覆盖了。 我的下一个想法是将缓冲区与图像交换到另一个后台线程,并阻止进行网络通信的主线程直到后台线程完成“显示”图像。 然后我听到它可以很容易地用SwingWorker
在这里:Can a progress bar be used in a class outside main?完成,但它完全一样的事情,如果我仍然在一个线程上做所有事情:没有图像显示。这里是我的代码:
public class ConnectionManager {
public static final String serverIp = "192.168.1.10";
public static final int tcpPort = 7;
public static final int bufferSize = 1280;
private Socket client;
private BufferedInputStream networkReader;
private PrintStream printStream;
byte[] buffer;
public ConnectionManager(){}
public void connect() throws IOException{
int dataRead;
while(true){
client = new Socket(serverIp, tcpPort);
printStream = new PrintStream(client.getOutputStream());
networkReader = new BufferedInputStream(client.getInputStream());
dataRead = 0;
buffer = new byte[1280 * 480];
printStream.println(""); // CR is code to server to send data
while(dataRead < (1280 * 480)){
dataRead += networkReader.read(buffer, dataRead, (1280 * 480) - dataRead);
}
DrawBack d = new DrawBack();
d.execute();
try {
d.get(); // here im trying to block main thread purposely
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
private class DrawBack extends SwingWorker<Void, Void>{
@Override
protected Void doInBackground() throws Exception {
byte Y, U, V;
int R, G, B, RGB, Yi, Ui, Vi;
boolean alternate = false;
for(int i = 0; i < 480; ++i){
for(int j = 1; j < 1280; j += 2){
if(alternate){
Y = buffer[i * 1280 + j];
V = buffer[i * 1280 + j -1];
U = buffer[i * 1280 + j -3];
} else {
Y = buffer[i * 1280 + j];
U = buffer[i * 1280 + j -1];
V = buffer[i * 1280 + j +1];
}
Yi = Y & 0xFF;
Ui = U & 0xFF;
Vi = V & 0xFF;
R = (int)(Yi + 1.402 * (Vi - 128));
G = (int)(Yi - 0.34414 * (Ui - 128) - 0.71414 * (Vi - 128));
B = (int)(Yi + 1.772 * (Ui - 128));
RGB = R;
RGB = (RGB << 8) + G;
RGB = (RGB << 8) + B;
alternate = !alternate;
Masapp.window.getImage().setRGB(j/2, i, RGB);// reference to buffered image on JFrame
if((i == 100) && (j == 479)){
System.out.println(Yi + " " + Ui + " " + Vi);
}
}
}
return null;
}
}
}
我甚至试图等待完成与同时:
DrawBack d = new DrawBack(); // DrawBack extends SwingWorker<Void, Void>
d.execute();
while(!d.isDone());
,但它并没有改善。当我设置所有像素时,我尝试调用BufferedImage.flush()
和JFrame.invalidate()
。
我的问题基本上是:如何定期刷新和显示缓冲图像?
看看http://stackoverflow.com/questions/6319465/fast-loading-and-drawing-of-rgb-data-in-bufferedimage – haraldK