2013-08-06 4 views
6

Я делаю программу, которая получает данные об изображении в массиве байтов с сервера. Я конвертирую эти данные в 24-битный формат BMP (будь то его jpeg, png, bmp или 8-24-32bpp). Во-первых, я сохраняю его на своем HD, а затем загружаю его в значок JLabel. Работает отлично, хотя есть некоторые случаи, в которых я получаю следующее исключение:Преобразование и отображение изображения из массива байтов

java.io.EOFException at 
javax.imageio.stream.ImageInputStreamImpl.readFully(ImageInputStreamImpl.java:353) at 
com.sun.imageio.plugins.bmp.BMPImageReader.read24Bit(BMPImageReader.java:1188) at 
com.sun.imageio.plugins.bmp.BMPImageReader.read(BMPImageReader.java:843) at 
javax.imageio.ImageIO.read(ImageIO.java:1448) at 
javax.imageio.ImageIO.read(ImageIO.java:1308) 

Для этой линии (второй)

File imgFile = new File("d:/image.bmp"); 
BufferedImage image = ImageIO.read(imgFile); 

В этих случаях:

  • изображение делает не загружайте в JLabel, но его можно найти на моем HD
  • преобразование не является правильным, потому что что-то «проскальзывает»
  • картина как при использовании курсива в текстовом документе

Во-первых, я думал, что, может быть, BPP является проблемой, то я подумал, что, может быть, картины слишком большие, но у меня есть случаи, это работает, и случаи это не для обоих предложений. Я немного застрял здесь и буду рад за идеи.

+1

Вы создали эти изображения? Все, о чем я могу думать, это то, что они созданы с некоторым форматом BMP, который ImageIO не поддерживает. Возможно, если вы попытаетесь отредактировать изображения и сохраните их снова. – Piro

+1

Я думаю, проблема в том, что некоторые фотографии не имеют байтов EOF, и именно поэтому вы получаете 'java.io.EOFException'. Я столкнулся с той же проблемой в формате jpeg. Имеет смысл, если вы считаете, что метаданные файла содержат информацию о длине файла, и поэтому EOF не понадобится. Этот факт объясняет, почему ваши файлы можно найти в вашем HD (и даже можно открыть, я думаю), но вы получаете исключение в java. – dic19

+1

Проверьте [это] (http: // stackoverflow.com/questions/12288813/exception-java-awt-color-cmmexception-invalid-image-format-throw-when-resizi/16858161 # 16858161), есть объяснение моего опыта работы с изображениями jpeg, которые, я надеюсь, будут полезно. – dic19

ответ

7
  • картина похожа. . При использовании курсива в текстовом документе

Думаю, что я, наконец, получил то, что эта пуля пункт имел в виду сейчас .. ;-)

Спекулятивный ответ, но здесь идет:

Если изображение вы пишете выглядит «перекос», это, вероятно, из-за недостающего для заполнения каждый столбец в формате BMP указывает (или неправильное поле ширины в заголовке BMP). Я предполагаю, что то, что изображения, которые вы получаете исключение EOF для, где ширина не кратна 4.

Try написать ВМР с помощью ImageIO, чтобы увидеть, если это помогает:

private static BufferedImage createRGBImage(byte[] bytes, int width, int height) { 
    DataBufferByte buffer = new DataBufferByte(bytes, bytes.length); 
    ColorModel cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[]{8, 8, 8}, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); 
    return new BufferedImage(cm, Raster.createInterleavedRaster(buffer, width, height, width * 3, 3, new int[]{0, 1, 2}, null), false, null); 
} 

.. .

byte[] bytes = ...; // Your image bytes 
OutputStream stream = ...; // Your output 

BufferedImage image = createRGBImage(bytes, width, height); 

try { 
    ImageIO.write(image, "BMP", stream); 
} 
finally { 
    stream.close(); 
} 
+0

вы гений, проблематичные изображения имеют ширину 618, 2671, 598 ... все остальные ширины кратные 4. – bajla

+1

@bajla Cool. Теперь я обновил ответ, с кодом для преобразования RGB-байтов в 'BufferedImage'. Вы можете использовать это, если только не выяснили, как правильно размещать данные изображения (из того, что я мог понять, оригинальный код Филиппа К. Хекеля сделал это правильно, но я только просматривал его). – haraldK

+0

Сэр, это абсолютное решение победителя! Спасибо за обновление. Я очень ценю это! Таким образом, отображение изображений происходит быстрее, и теперь оно работает во всех случаях! :) :) – bajla

0

Вы можете использовать этот код для преобразования выходного изображения в байтовый массив

Blob b = rs.getBlob(2); 
    byte barr[] = new byte[(int)b.length()]; //create empty array 
    barr = b.getBytes(1,(int)b.length()); 

    FileOutputStream fout = new FileOutputStream("D:\\sonoo.jpg"); 
    fout.write(barr); 
+0

Я не хочу конвертировать изображение в bytearray .. и что такое «rs» в первой строке? угадайте его изображение, но у меня нет изображения в первую очередь. – bajla

+0

rs - это объект ResultSet. –

2

Вызов его по имени класса, Лик ClassName.byteArrayToImage(byte):

public static BufferedImage byteArrayToImage(byte[] bytes){ 
     BufferedImage bufferedImage=null; 
     try { 
      InputStream inputStream = new ByteArrayInputStream(bytes); 
      bufferedImage = ImageIO.read(inputStream); 
     } catch (IOException ex) { 
      System.out.println(ex.getMessage()); 
     } 
     return bufferedImage; 
} 
Смежные вопросы