2011-08-24 19 views
21

Praca z obrazami w języku Java po raz pierwszy i otrzymuję wyjątki od dziwków, które nie są dobrze udokumentowane. Oto linia kodu, który zawodzi:Java ImageIO IIOException: nieobsługiwany typ obrazu?

BufferedImage imgSelected = ImageIO.read(new File("/abs/url/to/file/image.jpg")); 

Linia ta rzuca IIOException z Nieobsługiwane obrazu typu jako komunikat wyjątku. Sprawdziłem i ponownie sprawdziłem, czy to w rzeczywistości ta linia wyrzuca wyjątek, że obiekt File jest poprawny, że adres URL jest prawidłowy, i że image.jpg jest w rzeczywistości prawidłowym JPG, który ładuje się doskonale dobrze w innych przeglądarkach obrazów.

Co mogę zrobić, aby uzyskać więcej informacji na temat charakteru tego wyjątku? Czy jest to tradycyjny sposób ładowania obrazów w języku Java 7, czy jest to metoda stara/przestarzała? Nie ma zbyt wielu informacji na temat wyjątków "Nieobsługiwany typ obrazu", a na pewno ImageIO obsługiwane JPG!

Dzięki za pomoc!

Odpowiedz

27

Spróbuj sprawdzić kodowanie JPEG. ImageIO nie może na przykład odczytać obrazów jpeg zakodowanych w CMYK. AFAIK, ImageIO nie był aktualizowany od lat, więc chciałbyś spróbować użyć oficjalnej alternatywy/rozszerzenia: JAI ImageIO.

Niezawodnie, JAI ImageIO potrzebuje niektórych natywnych bibliotek zainstalowanych w środowisku JRE, co może być niepożądane. Robimy następujące:

  • użytku Apache Sanselan w celu wykrycia, czy to JPEG
  • od Sanselan nie może odczytywać i zapisywać w formacie JPEG, użyj zwykłego starego AWT JPEGCodec: JPEGCodec.createJPEGDecoder(...)
  • konwersji CMYK na RGB , my wtedy uzyskać raster odczytu BufferedImage i ręcznie przekonwertować go (można użyć profili ICC, ale instrukcja konwersji pasuje do naszych potrzeb)

Oto pytanie kopalni, które doprowadziły faktu, th pod numerem ImageIO nie obsługuje wszystkich typów obrazów JPEG, a ja podałem nieco więcej z moich ustaleń, dlaczego otrzymujesz tę wiadomość: Pure Java alternative to JAI ImageIO for detecting CMYK images

+0

Połów tutaj oczywiście jest to, że macierzyste biblioteki JAI ImageIO (przynajmniej w Windows) obsługują tylko 32-bitowe. – Trejkaz

9

Niestety, natknąłem się na wiele standardowych plików JPEG naruszających prawa. ImageIO jest szczególnie wybredny i często odmawia załadowania obrazów, które często są ładowane i widocznie poprawnie wyświetlane przez inne oprogramowanie z mniej rygorystyczną kontrolą formatu pliku.

To nie jest bardzo ładna, ale jeden obejście jest użycie Oracle VM wewnętrzny dekoder JPEG bezpośrednio (com.sun.image.codec.jpeg.JPEGCodec), gdyż wydaje się tolerować więcej odchyleń spec jak owijki ImageIO:

BufferedImage img = 
    JPEGCodec.createJPEGDecoder(inputStream).decodeAsBufferedImage(); 

Nie jest to oczywiście idealne rozwiązanie, ponieważ użycie klas związanych z implementacją spowoduje zablokowanie konkretnego dostawcy VM i może zepsuć się z nowszymi wersjami maszyn wirtualnych, ale jeśli będzie używane tylko w kontrolowanym środowisku, może to być lepsze niż żadne rozwiązanie.

+0

To świetna propozycja @jarnbjo. Dziękuję za poświęcenie czasu na odpowiedź na moje pytanie, zdecydowanie jedzenie do przemyślenia na drodze. – IAmYourFaja

+0

Próbowałem go na obrazie cmyk z powodu wyjątku, jak w temacie i nie powiodło się (wersja java "1.8.0_60"): com.sun.image.codec.jpeg.ImageFormatException: Nie plik JPEG: zaczyna się od 0xce 0x08 \t w sun.awt.image.codec.JPEGImageDecoderImpl.readJPEGStream (Metoda natywna) ~ [?: 1.8.0_60] – yetanothercoder

Powiązane problemy