[英]Transfer an image as byte array
我正在尝试从“服务器”发送图像,该服务器的目的是将图像发送到作为Android设备的“客户端”。 两者之间的插槽保持打开状态,并且图像不断出现。 问题是:
在下面的代码中:
-1
),它将在套接字关闭时停止。 最初,我尝试发送2个我知道大小(均相同)的BMP图像。 这是服务器代码:
public static void main(String[] args) {
try {
ServerSocket s = new ServerSocket(4488);
System.out.println("Waiting for a connection . . . . ");
Socket socket = s.accept();
System.out.println("Connected!");
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
Thread.sleep(2000);
File myImageFile = new File("c:\\1\\a.bmp");
FileInputStream fis = new FileInputStream(myImageFile);
byte[] data = new byte[(int) myImageFile.length()];
byte[] tmp = new byte[0];
byte[] myArrayImage = new byte[0];
int len = 0 ;
int total = 0;
while( (len = fis.read(data)) != -1 ) {
total += len;
tmp = myArrayImage;
myArrayImage = new byte[total];
System.arraycopy(tmp,0,myArrayImage,0,tmp.length);
System.arraycopy(data,0,myArrayImage,tmp.length,len);
}
//
fis.close();
dataOutputStream.write(myArrayImage);
dataOutputStream.flush();
Thread.sleep(2000);
myImageFile = new File("c:\\1\\b.bmp");
fis = new FileInputStream(myImageFile);
data = new byte[(int) myImageFile.length()];
tmp = new byte[0];
myArrayImage = new byte[0];
len = 0 ;
total = 0;
while( (len = fis.read(data)) != -1 ) {
total += len;
tmp = myArrayImage;
myArrayImage = new byte[total];
System.arraycopy(tmp,0,myArrayImage,0,tmp.length);
System.arraycopy(data,0,myArrayImage,tmp.length,len);
}
fis.close();
dataOutputStream.write(myArrayImage);
dataOutputStream.flush();
Thread.sleep(2000);
socket.close();
s.close();
这是客户端代码:
@Override
public void run() {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] byteChunk = null;
int c;
if (_dataInputStream != null) {
while (true) {
try {
Thread.sleep(200);
} catch (Exception e) {
}
try {
byteChunk = new byte[1024];
while ((c = _dataInputStream.read(byteChunk)) != -1){
buffer.write(byteChunk, 0, byteChunk.length);
}
} catch (IOException e) {
e.printStackTrace();
}
final Bitmap bitmap = BitmapFactory.decodeByteArray(buffer.toByteArray(), 0, buffer.size());
if (bitmap != null) {
_handler.post(new Runnable() {
public void run() {
_iv.setImageBitmap(bitmap);
_iv.invalidate();
}
});
}
buffer.reset();
}
}
}
现在,正如我所说,客户端一直停留在while循环中,直到套接字关闭为止,然后(无论我发送多少图像,因为我在客户端创建了仅适合1个图像的字节数组),它一直在读取一直都是第一张图片。
有什么想法我做错了吗?
Ps如果图像不是BMP,我在客户端代码中编写的解码是否可以工作? 我要发送的真实图像是PNG。
除非使用某种机制指示输入结束,否则客户端无法知道何时停止从流中读取。
一个简单的解决方法是使用固定长度(四个字节,一个int可以满足大多数图像)的标头,该标头写入流中,该值告诉客户端以下数据的长度。 然后,客户端从流中读取该字节数,然后停止并等待另一个报头或关闭流。
另一种方法是使用文件结尾定界符来通知客户端已遇到输入结尾。
除非在输入后关闭流,否则您将不得不在流中除了图像本身之外还要写入一些其他数据(元数据)。
只查看了您的客户端代码,但这不适合注释。 您需要重新考虑自己在做什么; 您的想法( 我第一次尝试做的是相同的事情)是基于人的而非基于计算机的。 换句话说,您的代码对我 (人类) 来说是有意义的,但是我真的不知道为什么,并且对计算机也没有意义。
要点: while (true)
循环没有退出-它是无限的。 我希望它会重复重复最后一次读入“位图”的操作。
首先,我要摆脱sleep
代码。 现在,这个问题令人困惑,如果有帮助,您可以稍后再放回去。 (我认为不会,您的读取将完成所有必要的阻塞操作。)然后,当读取完完整的图像后,您需要一个图像结束标记或某些东西来使您脱离读取循环。 (或者让它触发放置在此循环内的图像处理代码。)
最后,您需要一个文件结尾或图像结尾标记来将您踢出while (true)
循环。 (返回到“要点”。)
嗨,但是,如果您想读取jpeg
文件,则可以使用此代码
byte[] bytes = new byte[1024 * 1024];
int count = 0;
do
{
count += in.read(bytes, count, bytes.length - count);
}while (!(count > 4 && bytes[count - 2] == (byte) -1 && bytes[count - 1] == (byte) -39));
但我不明白如何读取PNG
格式
您可以先发送图像字节数组的大小,然后在while循环中读取字节,直到达到如下大小:
DataInputStream in = conn.openDataInputStream();
// read a length first
int length = in.readInt();
if (length <= 0) {
throw new IOException("Can't read a length");
}
// read the image now
imgData = new byte[length];
length = 0;
while (length != imgData.length) {
int n = in.read(imgData, length, imgData.length - length);
if (n == -1) {
throw new IOException("Can't read a image data");
}
length += n;
}
in.close();
请注意,图像的大小为int且具有多个字节,那么您需要使用writeint。
如果要发送PNG,请阅读有关格式的一些信息( Wiki )。 每个块都有前缀长度,因此您可以通过网络将其原始发送,并知道何时完成!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.