Я отправляю bufferedImage через сокет, и я использую пример, найденный в этом сообщении:
Отправитель
BufferedImage image = ....;
ImageIO.write(image, "PNG", socket.getOutputStream());
Приемник
BufferedImage image = ImageIO.read(socket.getInputStream());
Это работает - ЕСЛИ и ТОЛЬКО ЕСЛИ я закрываю outputStream отправителя после этой строки:
ImageIO.write(image, "PNG", socket.getOutputStream());
Могу ли я что-нибудь сделать, кроме закрытия outputStream?
Кроме того, могу ли я что-нибудь сделать, чтобы вообще не использовать ImageIO? Кажется, требуются годы, чтобы сделать что-нибудь.
Также обратите внимание, что в любом случае следует избегать чтения или записи на жесткий диск из-за проблем с производительностью. Мне нужно сделать эту передачу как можно быстрее (я экспериментирую и пытаюсь создать клиента, похожего на VNC, и сохранение каждого снимка экрана на жесткий диск сильно замедлит все) ..
@ Джон Скит
Редактировать 3:
Отправитель: (обратите внимание, что я отправляю изображение JPG, а не PNG).
int filesize;
OutputStream out = c.getClientSocket().getOutputStream();
ByteArrayOutputStream bScrn = new ByteArrayOutputStream();
ImageIO.write(screenshot, "JPG", bScrn);
byte[] imgByte = bScrn.toByteArray();
bScrn.flush();
bScrn.close();
filesize = bScrn.size();
out.write(new String("#FS " + filesize).getBytes()); //Send filesize
out.write(new String("#<IM> \n").getBytes()); //Notify start of image
out.write(imgByte); //Write file
System.out.println("Finished");
Приемник: (где input
- входной поток сокета)
Попытка № 1:
String str = input.toString();
imageBytes = str.getBytes();
InputStream in = new ByteArrayInputStream(imageBytes);
BufferedImage image = ImageIO.read(in);
in.close();
System.out.println("width=" + image.getWidth());
(ошибка: исключение Nullpointer в строке getWidth ())
Я понимаю, что эта ошибка означает «испорченное изображение», потому что она не может его инициализировать. исправить?
Попытка № 2:
byte[] imageBytes = new byte[filesize];
for (int j = 0; i < filesize; i++)
{
imageBytes[j] = (byte) input.read();
}
InputStream in = new ByteArrayInputStream(imageBytes);
BufferedImage image = ImageIO.read(in);
in.close();
System.out.println("width=" + image.getWidth());
(ошибка: исключение Nullpointer в строке getWidth ())
Попытка № 3:
if (filesize > 0)
{
int writtenBytes = 0;
int bufferSize = client.getReceiveBufferSize();
imageBytes = new byte[filesize]; //Create a byte array as large as the image
byte[] buffer = new byte[bufferSize];//Create buffer
do {
writtenBytes += input.read(buffer); //Fill up buffer
System.out.println(writtenBytes + "/" + filesize); //Show progress
//Copy buffer to the byte array which will contain the full image
System.arraycopy(buffer, 0, imageBytes, writtenBytes, client.getReceiveBufferSize());
writtenBytes+=bufferSize;
} while ((writtenBytes + bufferSize) < filesize);
// Read the remaining bytes
System.arraycopy(buffer, 0, imageBytes, writtenBytes-1, filesize-writtenBytes);
writtenBytes += filesize-writtenBytes;
System.out.println("Finished reading! Total read: " + writtenBytes + "/" + filesize);
}
InputStream in = new ByteArrayInputStream(imageBytes);
BufferedImage image = ImageIO.read(in);
in.close();
(ошибка: получатель выдает: исключение нулевого указателя)
Попытка 4:
int readBytes = 0;
imageBytes = new byte[filesize]; //Create a byte array as large as the image
while (readBytes < filesize)
{
readBytes += input.read(imageBytes);
}
InputStream in = new ByteArrayInputStream(imageBytes);
BufferedImage image = ImageIO.read(in);
in.close();
System.out.println("width=" + image.getWidth());
(ошибка: отправитель дает: java.net.SocketException: сброс соединения по пиру: ошибка записи в сокет)
Попытка № 5:
Используя фрагмент кода Джона Скита, изображение прибывает, но только частично. Я сохранил его в файл (1.jpg), чтобы увидеть, что происходит, и он на самом деле отправляет 80% изображения, в то время как остальная часть файла заполнена пробелами. Это приводит к частично поврежденному изображению. Вот код, который я пробовал: (обратите внимание, что captureImg () не виноват, сохранение файла напрямую работает)
Отправитель:
Socket s = new Socket("127.0.0.1", 1290);
OutputStream out = s.getOutputStream();
ByteArrayOutputStream bScrn = new ByteArrayOutputStream();
ImageIO.write(captureImg(), "JPG", bScrn);
byte imgBytes[] = bScrn.toByteArray();
bScrn.close();
out.write((Integer.toString(imgBytes.length)).getBytes());
out.write(imgBytes,0,imgBytes.length);
Ресивер:
InputStream in = clientSocket.getInputStream();
long startTime = System.currentTimeMillis();
byte[] b = new byte[30];
int len = in.read(b);
int filesize = Integer.parseInt(new String(b).substring(0, len));
if (filesize > 0)
{
byte[] imgBytes = readExactly(in, filesize);
FileOutputStream f = new FileOutputStream("C:\\Users\\Dan\\Desktop\\Pic\\1.jpg");
f.write(imgBytes);
f.close();
System.out.println("done");
Отправитель по-прежнему выдает сброс соединения по адресу peer: ошибка записи в сокет.
Нажмите здесь для полноразмерного изображения