Восстановить образ байтового массива - PullRequest
0 голосов
/ 09 мая 2011

Я пытаюсь получить изображение, закодированное в байтовом массиве.

Хорошо работает, если изображение не слишком большое, но когда мне приходится много раз читать входной поток, чтобы получить всебайты изображения, строка:

BufferedImage img = ImageIO.read(new ByteArrayInputStream(finalData));

возвращает null.

Вот мой код:

byte[]imgSize = new byte[SIZE_OF_LENGTH_ARRAY];
bis.read(imgSize, 0, SIZE_OF_LENGTH_ARRAY);
ByteBuffer bb = ByteBuffer.wrap(imgSize);
int size = bb.getInt();

System.out.println("Client: size="+size);
byte[] tmpData = new byte[size];
System.out.println("tmpData length = "+tmpData.length);
int readen = bis.read(tmpData, 0, tmpData.length);
System.out.println("readen="+readen);

byte[]finalData = new byte[size]; 

if(readen == size){
    finalData = tmpData;
}
else{
    int totalRead = readen;
    int j=1;

    while(totalRead<size){
        System.out.println("-----------append number "+j+"----------");
        System.out.println("totalRead="+totalRead);

        for(int i=0;i<tmpData.length;i++){
            finalData[i]=tmpData[i];
        }

        tmpData = new byte[size-totalRead];
        int tmpRead = bis.read(tmpData, 0, size-totalRead);
        System.out.println("tmpRead="+tmpRead);

        for(int i=0;i<tmpData.length;i++){
            finalData[i+totalRead]=tmpData[i];
        }

        totalRead+=tmpRead;
        j++;
    }
    System.out.println("totalRead final="+totalRead);
}

BufferedImage img = ImageIO.read(new ByteArrayInputStream(finalData));

И пример вывода:

---Client: sending mess number 1---
Client: size=31099
tmpData length = 31099
readen=31099
---Client: sending mess number 2---
Client: size=85921
tmpData length = 85921
readen=17520
-----------append number 1----------
totalRead=17520
tmpRead=17520
-----------append number 2----------
totalRead=35040
tmpRead=17520
-----------append number 3----------
totalRead=52560
tmpRead=31408
-----------append number 4----------
totalRead=83968
tmpRead=1953
totalRead final=85921
image null

Хотя я хорошо прочитал 85921 байт, ImageIO.Read создает нулевое изображение.

Ответы [ 2 ]

0 голосов
/ 09 мая 2011

Эта строка может перезаписывать байты из предыдущей итерации:

 while(totalRead<size){
        System.out.println("-----------append number "+j+"----------");
        System.out.println("totalRead="+totalRead);
        //I suspect this is unnecessary and one source of the error
        //this loop would overwrite data from the last iteration's tmpData
        for(int i=0;i<tmpData.length;i++){ 
            finalData[i]=tmpData[i];
        }
        tmpData = new byte[size-totalRead];
        int tmpRead = bis.read(tmpData, 0, size-totalRead);
        System.out.println("tmpRead="+tmpRead);
        for(int i=0;i<tmpData.length;i++){
            finalData[i+totalRead]=tmpData[i];  //append tmpData
        }
        totalRead+=tmpRead;
        j++;
    }

Предположим, что вы читаете 10 байтов в каждой итерации.

В первом запуске выустановите все элементы конечных данных в 0, затем прочитайте 10 байтов и установите элементы 0-9 в finalData.

Во второй итерации вы теперь перебираете содержимое tmpData (которое является байтами 0-9) и перезаписываетебайты от 0-9 до до чтения байтов 10-19 и добавления их.(пока все хорошо)

В третьей итерации вы перебираете содержимое tmpData (которое теперь является байтами 10-19 со второй итерации) и перезаписываете байты 0-9 в finalData.Итак, вот одна ошибка.

0 голосов
/ 09 мая 2011

Я не знаю, что такое бис, но эта строка, вероятно, неверна:

bis.read(imgSize, 0, SIZE_OF_LENGTH_ARRAY);

Вы всегда должны проверять возвращаемое значение из чтения. Чтение может читать меньше, чем вы указали.

Edit:

Вот как вы обычно читаете все данные из потока:

byte[] buffer = new byte[1024 * 32];
int len = 0;
while ((len = in.read(buffer)) > -1) {
    out.write(buffer, 0, len);
}

Редактировать 2:

Но почему вы не делаете что-то вроде:

ImageIO.read(bis);
...