Warum liest ImageIO eine BMP-Datei nicht, bis sie in MS Paint erneut gespeichert wird?

  • Ich habe eine Bitmap-Datei test3.bmp, die ich mit jedem Bildbetrachter, den ich getestet habe, anzeigen und bearbeiten kann.

    Das sagte, Ich kann es nicht in meine Java-Anwendung einlesen. Wenn ich das BMP in MS Paint bearbeite, speichere es, mache die Änderung rückgängig und speichere es (test3_resaved.bmp). Ich habe das gleiche Bild, aber mit einer anderen Dateigröße. Die unterschiedlichen Dateigrößen betreffen mich nicht ... was bedeutet, dass meine Anwendung die wiedergespeicherte Datei lesen kann.

    Könnte mich jemand darüber informieren, warum ein Bild mit meinem funktioniert? Code aber der andere nicht?

    Bilddateien:

    22 November 2011
    Thomas Eding
3 answers
  • (erweitert meine Kommentare)

    Das Problem läuft darauf hinaus: Die Leute glauben normalerweise, dass das "Format", das von der folgenden Befehl:

     ImageIO.getReaderFileSuffixes();
     

    werden von Java unterstützt.

    Aber so sollte es nicht gelesen / verstanden werden, weil es einfach nicht so ist.

    Falsch: "ImageIO kann jede Datei lesen, die mit einem dieser Formate codiert ist"

    Korrigieren: "ImageIO kann kein Bild lesen, das mit einem Format codiert ist, das nicht einem dieser Formate entspricht"

    Aber was sagt das nun über Formate in dieser Liste? Nun, es wird schwierig.

    Diese Liste gibt zum Beispiel normalerweise "PNG" und "BMP" (und andere Formate) zurück. Es gibt jedoch weder "eine" PNG noch "eine" BMP. Ich kann morgen mit einem "gültigen" PNG (Sub) -Format kommen, das vollkommen in Ordnung wäre, aber kein einzelner PNG-Decoder da draußen dekodieren würde (er müsste validiert und akzeptiert werden; aber wenn er akzeptiert würde, würde er "brechen" msgstr "alle vorhandenen PNG - Decoder da draußen). Glücklicherweise ist das Problem für die PNG-Bilder nicht so schlimm.

    Das BMP-Format ist sehr kompliziert. Sie können eine Komprimierung haben oder nicht (was möglicherweise die unterschiedliche Dateigröße erklärt, die Sie gesehen haben). Sie können verschiedene Kopfzeilen haben (von unterschiedlicher Länge, die möglicherweise auch die unterschiedliche Dateigröße erklären). Heck, BMP ist eigentlich so komplex, dass ich denke, dass Sie PNG-codierte Pixel in eine BMP- "Shell" einbetten können.

    Grundsätzlich gibt es zwei Arten von BMP-Dateien:

Der "Fehler" besteht darin zu denken, dass es ein PNG- oder ein BMP-Format gibt. Beide Formate (und auch andere Bildformate) sind eigentlich "erweiterbar".

22 November 2011
TacticalCoderSergey
  • Ich habe die beiden Images mit meinem eigenen Java BMP-Decoder getestet. Außerdem werden einige Informationen des Bildes ausgegeben. Ich habe festgestellt, dass das Original ein 32-Bit-BMP ist und das wiedergespeicherte ein 24-Bit-Bit ist. Ich gehe also davon aus, dass der Imageio-BMP-Reader 32-Bit-BMP nicht richtig verarbeiten kann.

    Update: Um zu bestätigen, dass ich schon lange nicht mehr gedacht habe, habe ich das Image noch einmal getestet und ist immer noch problematisch. Das Problem ist, dass kein Bild angezeigt wird. Java ImageIO ist der Ansicht, dass das Bild vollständig transparent ist. Folgendes ist ein von Java ImageIO erstelltes BufferedImage:

      DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=ff000000
     IntegerInterleavedRaster: width = 494 height = 516 #Bands = 4 xOff = 0 yOff = 0
     dataOffset[0] 0
     java.awt.image.SinglePixelPackedSampleModel@80809ee
     

    Wir sehen hier 4 Bänder, die RGBA darstellen als Java ImageIO interpretierte es. Die Wahrheit ist das vierte Band oder das vierte Byte ist kein Alphakanal für ein 32-Bit-Windows-BMP-Image. Es ist einfach Müll oder um es mit einem Doppelwort auszurichten.

    Ein Windows 3.x BMP-Decoder und vieles mehr hier https://github.com/dragon66/icafe

    12 January 2015
    dragon66
  • Hier ist ein Beispielcode. http: // www.java2s.com/Code/Java/2D-Graphics-GUI/ListAllreaderandwriterformatssupportedbyImageIO.htm , das unterstützte Bildformate von Ihrem JDK auflistet.

    BMP wird von unterstützt das erweiterte Image-Toolkit http: // www .oracle.com / technetwork / java / release-jai-imageio-1-0-01-140367.html aber ich weiß, dass es auch Dinge enthält, die jetzt auch vom Basis-JDK unterstützt werden. Wenn sie also von beiden unterstützt wird, ist die JAI-Unterstützung möglicherweise umfassender. Das erscheint jedoch unwahrscheinlich, da es nicht viel Sinn macht. OTOH, war Sun.

    Wenn Sie JDK 6 verwenden, können Sie definitiv PNG (was portabler ist) machen, können Sie Ihr konvertieren Bilder? IIRC MS Paint speichert eine PNG.

    22 November 2011
    Bill