Verwendung gängiger Bilddateiformate in Ihren BASIC-Projekten

Warum sind BLOAD und BSAVE nicht mehr zeitgemäss?

In vielen Büchern wird für das Laden und Speichern von Grafiken auf BLOAD und BSAVE verwiesen. Im heutigen Zeitalter von Internet und Vernetzung und damit verbunden die Forderung nach sog. Datendurchgängigkeit und Interoperabilität sind BLOAD und BSAVE nicht mehr zeitgemäss, da BSAVE ein proprietäres Dateiformat erzeugt. Kein anderes Programm kann also damit etwas anfangen, ausser QuickBASIC selber. Seien Sie sich auch bewusst, dass heutzutage eigentlich niemand mehr direkt mit PSET, LINE, CIRCLE, PAINT usw. seine Grafiken direkt in den BASIC-Quellcode fest hineincodiert. In der Software-Industrie und allen Web-Design-Firmen wird schon lange mit professionellen Bildbearbeitungswerkzeugen gearbeitet. Damit diese Software-Werkzeuge die Bilddaten untereinander austauschen können, werden standardisierte Dateiformate wie GIF, JPEG, PNG, TIFF usw. eingesetzt.

Auch für Sie als Hobby-Programmierer eröffnet die Verwendung dieser Standard-Dateiformate neue Möglichkeiten:

Dieser Artikel soll Ihnen das nötige Wissen mitgeben, um dieses Potential voll ausschöpfen zu können.

Was braucht es dazu und wieviel davon wird von QuickBASIC unterstützt?

Im wesentlichen geht es darum, geeignete Unterprogramme für das Laden sowie Speichern von Bildern zur Verfügung stellen. Dazu bietet QuickBASIC folgende beiden Schnittstellen an:

Bei Bitmap-Dateien müssen wir ausserdem noch zwischen Echtfarben (TrueColor) und Palette unterscheiden. Da QuickBASIC von sich aus nur Palettengrafik unterstützt (es sei denn, Sie verwenden die SuperVGA-Videomodi über die VESA-Schnittstelle), wird hier in erster Linie auch nur auf Palettengrafik mit den bekannten maximal 256 gleichzeitigen Farben eingegangen.

Leider :-( besitzt QuickBASIC von Haus aus noch keinerlei Unterstützung diesbezüglich, so dass es dem BASIC-Programmierer selber überlassen wird, solche Routinen zu implementieren, weshalb überhaupt dieser Artikel entstand.

Gibt es schon fertige Laderoutinen im Internet dazu?

Nach meiner Erfahrung existieren recht viele solche Routinen; eine Fundgrube ist sicher der Download-Bereich der QuickBASIC-Homepage. Aber auch auf allgemeinen Suchmaschinen wie Altavista werden Sie recht rasch fündig.

Die Qualität dieser Programme ist jedoch recht unterschiedlich; sehr häufig beschränken sich diese Laderoutinen nur auf ganz bestimmte Unterformate (z.B. nur schwarzweisse PCX-Grafiken), ebenso wird häufig der Dateikopf nur ungenügend ausgewertet, so dass anstelle einer klaren not implemented yet-Meldung das Programm irgendwann abstürzt, ebenso fehlt auch häufig ein sauberes Design als Unterprogramme. Dennoch sind diese Routinen häufig sehr lehrreich, um ein bestimmtes Dateiformat näher kennenlernen zu können!

Von mir selber entwickelte Grafikladeroutinen

Hier möchte ich Sie wärmstens auf die Windows Bitmap-Bibliothek für .BMP-Grafikdateien verweisen, wo Sie auch nebst einer ausführlichen Dokumentation im Quellcode sehr viele Details herauslesen können. Für Amiga-Fans existiert in Knoblifax eine Laderoutine für .IFF-Dateien (IFF/ILBM), dem Standardformat bei Commodore.

Selber eine Lade- und/oder Speicherroutine schreiben

In diesem Abschnitt möchte ich Ihnen Tips auf den Weg mitgeben, damit Sie Ihre eigene Lade- und Speicherroutine erfolgreich erstellen können.

Zuerst einmal brauchen Sie sich die Spezifikationen zum Dateiformat beschaffen. Dazu einige Quellen:

Ideal sind aus meiner Sicht immer wenn möglich die Originalspezifikationen, also beispielsweise bei GIF dasjenige Dokument, welches Compuserve 1987 herausgab, bei IFF dasjenige von Electronic Arts von 1985 usw., sofern überhaupt vorhanden und auffindbar.

Bevor Sie gleich mit der eigentlichen Laderoutine beginnen, empfiehlt sich zu Beginn, mit möglichst vielen verschiedenen(!) Grafikprogrammen eine kleine Sammlung Musterdateien anzulegen, ebenso ist ein geeignetes Hexdump-Utility wie Norton Commander ebenfalls hilfreich. Unter UNIX und Linux können Sie mit dem od-Befehl Dateien als Hexdump ausgeben lassen:

linuxbox:/home/user > od -t x1 musterd1.gif|more
0000000 47 49 46 38 37 61 2b 00 22 00 f3 05 00 84 84 84
0000020 00 ff ff 00 00 ff 00 00 00 c6 c6 c6 ff ff ff 00
0000040 00 00 00 00 00 84 84 84 00 ff ff 00 00 ff 00 00
0000060 00 c6 c6 c6 ff ff ff 00 00 00 7b 7b 7b 2c 00 00
0000100 00 00 2b 00 22 00 03 04 a6 b0 c8 49 ab bd 38 eb
0000120 cd bb ff 60 28 8e 64 69 76 43 aa ae 6c db 7e c3
0000140 49 c5 5c 4c dc 78 ae ef 3b 40 6b 36 02 60 48 2c
0000160 1a 8f c3 9b af 56 10 ba 9e cf e6 72 63 f3 05 08
0000200 d7 2c 76 ab ed 56 7f 99 2f 77 dc 25 13 be 4c 27
0000220 74 ad 92 82 31 68 52 1c e8 2e cd c3 f5 82 60 cf
0000240 ef fb f7 12 77 70 79 23 82 17 71 7f 89 7c 13 86
...

Mit etwas Phantasie können Sie mit Hilfe von HEX$() und dem Binär-Dateimodus auch in QuickBASIC selber einen kleinen Hexdumper schreiben :-).

Als nächstes sollten Sie alle wichtigen Header-Passagen einmal etwas näher analysieren: Dazu bietet es sich an, die eingelesenen Werte mit PRINT anzeigen zu lassen. Beispiel von mir:

INPUT "Muster-BMP-Datei"; d$
OPEN d$ + ".bmp" FOR BINARY AS 2
PRINT "physikalische Länge:"; LOF(2); "Bytes"
PRINT
IF LOF(2) > 54& THEN
  PRINT "Abschnitt BITMAPFILEHEADER:"
  PRINT "Kennung : "; INPUT$(2, 2)
  l& = CVL(INPUT$(4, 2))
  PRINT "Logische Länge :"; l&; "Bytes:";
  IF l& <> LOF(2) THEN
    COLOR 12: PRINT "weicht ab"
  ELSE
    COLOR 10: PRINT "gleich gross"
  END IF
  COLOR 7
  PRINT "Erstes reserviertes Wort :"; CVI(INPUT$(2, 2))
  PRINT "Zweites reserviertes Wort :"; CVI(INPUT$(2, 2))
  e& = CVL(INPUT$(4, 2))
  PRINT "Entfernung der Bitmap-Daten:"; e&; "Bytes"
  PRINT
  l2& = CVL(INPUT$(4, 2))
  PRINT "Abschnitt BITMAPINFOHEADER :"; l2"; "Bytes gross"
  PRINT "Bildbreite :"; CVL(INPUT$(4, 2)); "Pixel"
  PRINT "Bildhöhe :"; CVL(INPUT$(4, 2)); "Pixel"
  PRINT "Anzahl Bitplanes :"; CVI(INPUT$(2, 2))
  PRINT "Anzahl Bit pro Bildpunkt :"; CVI(INPUT$(2, 2))
  c& = CVL(INPUT$(4, 2))
  PRINT "Kompression : ";
  SELECT CASE c&
  CASE 0&
    PRINT "keine"
  CASE 1&
    PRINT "RLE8-Verfahren"
  CASE 2&
    PRINT "RLE4-Verfahren"
  CASE ELSE
    PRINT "unbekannte Methode :"; c&
  END SELECT
  PRINT "Bildgrösse"; CVL(INPUT$(4, 2)); "Bytes"
  hdpi& = CVL(INPUT$(4, 2))
  PRINT "Horizontale Punktdichte:"; hdpi&; "Pixel pro Meter ("; 127# * CDBL(hdpi&) / 5000#; "dpi [Dots per Inch])"
  vdpi& = CVL(INPUT$(4, 2))
  PRINT "Vertikale Punktdichte:"; vdpi&; "Pixel pro Meter ("; 127# * CDBL(vdpi&) / 5000#; "dpi [Dots per Inch])"
  PRINT "Anzahl benutzte Farben :"; CVL(INPUT$(4, 2))
  PRINT "Anzahl wichtige Farben :"; CVL(INPUT$(4, 2))
END IF
CLOSE 2

Das Analysieren möglichst vieler Dateien auf diese Art und Weise ist aus meiner Sicht eine der lehrreichsten Tätigkeiten überhaupt. Gleichzeitig erhalten Sie auch sehr viele Aha-Erlebnisse, denn Sie stossen beispielsweise auch ab und zu einmal auf Formatfehler, welche auch zeigen, dass die Software-Entwickler professioneller Werkzeuge auch nur Menschen wie Sie und ich sind. Aber zugleich beseitigt eine solche Analyse auch Unklarheiten (bei mir war es beispielsweise seinerzeit das Feld »Anzahl wichtige Farben« vom obigen Beispiel), denn häufig sehen Sie nur aufgrund konkreter Werte, was bestimmte Felder bedeuten.

Nachdem Sie sich reichlich »schlau gemacht« haben, können Sie die eigentliche Routine vollständig ausprogrammieren.

Zum Testen verwenden Sie wiederum Ihre zu Beginn angelegte Bildersammlung und achten insbesondere darauf, dass Ihre Routine mit jeder Datei zurecht kommt. Generell möchte ich Ihnen empfehlen, zuerst einmal nur die Laderoutine zu programmieren. Erst, wenn diese absolut fehlerfrei läuft, können Sie die Speicherroutine erstellen. Im dortigen Fall besteht der Software-Test darin, die mit Ihrem BASIC-Programm erzeugte Grafikdatei zunächst einmal mit dem obigen PRINT-Zeilenprogramm analysieren (nach meiner Erfahrung werfen recht viele Windows-Programme mit einer Schutzverletzung das Handtuch, sobald sie eine fehlerhafte Datei bekommen!) und dabei jede Ausgabe genauestens kontrollieren. Sobald dort alles stimmt, versuchen Sie die erzeugte Datei mit Ihrer eigenen Laderoutine zu öffnen (Vorteil: BASIC produziert nur harmlose Fehlermeldungen statt Schutzverletzungen, welche Ihnen Hinweise auf die noch fehlerhaften Stellen der Schreibroutine liefern). Sobald auch dies klappt, versuchen Sie sie innerhalb von DOS und Windows mit möglichst vielen Grafikwerkzeugen zu öffnen, z.B. hier mit dem Windows-eigenen Programm Paint, dann Corel PhotoPaint, Microsoft PhotoExpress, Einbinden in ein Word-Dokument usw. wobei Ihre Datei auch hier ohne eine einzige Ausnahme fehlerfrei arbeiten sollte. Erst danach gilt Ihre BASIC-Routine als ausgereift und voll einsatzbereit.


Wieder zurück zur Übersicht


© 2000 by Andreas Meile