2013-08-06 25 views
6

Tworzę program, który pobiera dane o obrazie z tablicy bajtów z serwera. Konwertuję te dane do formatu 24-bitowego BMP (niezależnie od tego, czy jest to jpeg, png, bmp, czy 8-24-32bpp). Po pierwsze, zapisuję go w mojej HD, a następnie ładuję go do ikony JLabel. Działa perfekcyjnie, choć istnieją pewne przypadki, w których pojawia się następujący wyjątek:Konwertuj i wyświetlaj obraz z tablicy bajtów

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) 

dla tej linii (drugi)

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

w następujących przypadkach:

  • obraz robi nie ładuje się do JLabel, ale można go znaleźć na mojej HD
  • konwersja nie jest właściwa, ponieważ coś "ześlizguje się"
  • obraz jest jak podczas korzystania z kursywy w dokumencie programu Word

początku myślałem, że być może BPP jest problem, potem pomyślałem, że może zdjęcia są zbyt duże, ale mam przypadków to działa i przypadki nie dotyczy obu sugestii. Trochę utknąłem tutaj i będę zadowolony z pomysłów.

+1

Czy stworzyłeś te obrazy? Wszystko, o czym mogę pomyśleć, to to, że są one tworzone z pewnym formatem BMP, którego nie obsługuje ImageIO. Może jeśli spróbujesz edytować zdjęcia i zapisać je ponownie. – Piro

+1

Myślę, że problem polega na tym, że niektóre obrazy nie mają bajtów EOF i dlatego uzyskujesz 'java.io.EOFException'. Doświadczyłem tego samego problemu z formatem 'jpeg'. Ma to sens, jeśli uważasz, że metadane pliku zawierają informacje o długości pliku i w konsekwencji EOF nie byłoby konieczne. Fakt ten wyjaśnia, dlaczego pliki można znaleźć w HD (a nawet można je otworzyć), ale w języku Java pojawia się wyjątek. – dic19

+1

Sprawdź [to] (http: // stackoverflow.com/questions/12288813/exception-java-awt-color-cmmexception-invalid-image-format-throw-when-resizi/16858161 # 16858161) link, istnieje wyjaśnienie mojego doświadczenia w pracy z obrazami 'jpeg', które mam nadzieję być pomocny. – dic19

Odpowiedz

7
  • obraz jest podobny. Podczas używania kursywy w dokumencie tekstowym

Think I wreszcie, co pozycja ta kula przeznaczona teraz .. ;-)

odpowiedź spekulatywna, ale tu idzie:

Jeśli obraz piszesz wygląda „przekrzywiony”, to prawdopodobnie z powodu braku dopełnienia dla każda kolumna określona jako format BMP (lub nieprawidłowe pole szerokości w nagłówku BMP). Zakładam więc, że obrazy można dostać za wyjątki EOF, gdzie szerokość nie jest wielokrotnością 4.

spróbować napisać BMP przy użyciu ImageIO aby zobaczyć czy to pomaga:

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

jesteś geniuszem, problematyczne obrazy mają szerokość 618, 2671, 598 ... wszystkie pozostałe są wielokrotnością 4. – bajla

+1

@bajla Cool. Zaktualizowałem teraz odpowiedź, używając kodu do konwertowania bajtów RGB na "BufferedImage". Możesz tego użyć, chyba że zorientowałeś się, jak poprawnie zabezpieczyć dane obrazu (z tego, co mogłem zrozumieć, oryginalny kod Philippa C. Heckela zrobił to poprawnie, ale tylko przejrzałem go). – haraldK

+0

Panie, to absolutne rozwiązanie dla zwycięzców! Dziękuję za aktualizację. Bardzo to doceniam! W ten sposób wyświetlanie obrazu jest szybsze, a teraz działa we wszystkich przypadkach! :) :) – bajla

0

Można użyć tego kodu, aby przekonwertować obraz wyjściowy do tablicy bajtów

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

Nie chcę konwertować obrazu na bytearray .. i co to jest "rs" w pierwszym wierszu? odgadnij jego obraz, ale nie mam obrazu na pierwszym miejscu. – bajla

+0

rs to obiekt ResultSet. –

2

Nazwijmy to po imieniu klasy, liek 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; 
}