Carl-Zeiss-Gymnasium Jena
Mirko König |
Darstellen von BMP-Bildern in einem ColorPlane-Fenster
|
| Vortrag zur Lehrerfortbildung |
13. 3. 2001 |
1. Bitmaps
2. Aufbau einer Bitmap-Datei
3. Benötigte Oberon-Module
4. Die Programme
5. Resümee
Literatur
1. Bitmaps
Als Bitmaps werden im engeren Sinne die Bilddateien im Format *.BMP, des Hausformates
von MS Windows und OS/2 für Pixelbilder, bezeichnet. Im weiteren Sinne gilt
der Begriff für sämtliche Pixelbilder
und darüberhinaus für Datenmengen in einem nicht näher spezifizierten
Byte-Format.
Diese Arbeit stellt sich zum Ziel, Möglichkeiten der Darstellung von BMP-Bildern
im einem Oberon-2-Programm unter Pow! aufzuzeigen.
Bitmaps gibt es in den in der Tabelle gezeigten Formen (von MS Paint verwendete
Bezeichnungen):
| Art des Bitmaps |
Anzahl der Farben |
Bits pro Pixel |
| Monochrom |
2 (schwarz und weiß) |
1 |
| 16-Farben-Bitmap |
16 |
4 |
| 256-Farben-Bitmap |
256 |
8 |
| 24-Bit-Bitmap |
16777216 |
24 (je 8 für rot, grün, blau) |
Von jeder Form gibt es eine unkomprimierte und eine komprimierte Form. Letztere
wird jedoch selten verwendet, insbesondere nicht von MS Paint.
Das führt insbesondere bei 24-Bit-Bitmaps zu enormen Dateigrößen.
Ein Rechenbeispiel: ein Bild von 800*600 Punkten mit 3 Bytes pro Pixel hat 1440000
Byte an Bilddaten, paßt also etwa auf eine Diskette. Trotzdem lohnt es
sich, die BMP-Dateien genauer anzusehen, denn ein Bildbearbeitungsprogramm braucht
den Zugriff auf jedes Pixel. So erzeugt eine harmlos aussehende JPG-Datei von
218 kB im Hauptspeicher des Browsers eine Speicherreservierung von 5,7 MB, wie
ein Blick auf die Statusleiste von Paint Shop zeigt - ein
Grund dafür, daß manche Rechner mit kleinem Speicher manche schnell
gestrickten HTML-Seiten nicht richtig zeigen können:

So ist das BMP-Format sozusagen ein ehrliches Format, denn es sagt uns, was
wir im Speicher zu erwarten haben.
Ich verwende an dieser Stelle unkomprimierte Bitmaps in 24-Bit-Farbe, d. h.
jeder Punkt ist mit je 8 Bit für die Grundfarben der additiven Farbmischung,
nämlich Rot, Grün und Blau kodiert. Dafür
gibt es 2 Gründe: Erstens kann ColorPlane sehr schön Bilder in 24-Bit-Farbe
zeigen, da eben für jeden Punkt die 3 Byte zur Verfügung
stehen. Außerdem sind Monochrombilder relativ uninteressant, und die 16-
sowie 256-Farben-Bilder benötigen eine Liste der verwendeten Farben, was
die Arbeit erschwert und zudem wenig interessante Ergebnisse
bringt.
24-Bit-Bilder stellen ein Optimum der Bildschirmanzeige dar, da das menschliche
Auge mehr Farbnuancen schon nicht mehr wahrnehmen kann, wie
die Gebrüder Geiß bereits festgestellt haben [1].
Jedoch macht sich bei Scannern 30- oder 36-Bit-Farbe erforderlich. Den Grund
werden wir in Abschnitt 4 sehen
2. Aufbau einer Bitmap-Datei
Die Bitmap-Datei enthält einen Vorspann (Header) und die Daten der Pixel
selbst [2].
| Datum |
Bytes |
Kommentar |
| File ID |
2 |
immer "BM" |
| Länge der Datei |
4 |
der Vorspann und die Bilddaten |
| Datenoffset |
4 |
= 0 |
| reserviert |
4 |
für spätere Verwendung |
| Infoheader |
4 |
Offset des Datenbereiches - dort fangen die Pixel an (= 54 bei 24-Bit-Farbe) |
| Breite |
4 |
Breite des Bildes in Pixeln |
| Höhe |
4 |
Höhe des Bildes in Pixeln |
| Farbebenen |
2 |
immer 1 (Farbebenen wurden bei BMPs nie eingeführt) |
| Bits pro Pixel |
2 |
24 in unserem Fall |
| weitere für 24-Bit-Farbe unwichtige Informationen |
24 |
|
16- und 256-Bit-BMPs haben an dieser Stelle noch die Liste der verwendeten Farben.
Diese ist bei 16 Millionen verwendeten Farben nicht sinnvoll.
| Pixeldaten |
3 pro Pixel. Nach jeder Zeile wird die Pixelfolge mit Null-Bytes auf
eine durch 4 teilbare Anzahl ergänzt. |
in der Reihenfolge blau, grün, rot. Der erste Punkt steht links
unten. |
3. Benötigte Oberon-Module
Ich verwende das 32-Bit-Pow!, da es die Speicherung der Pixel in einem ausreichend
großen Array gestattet. Sinngemäß ist das Laden von Bitmaps
auch mit dem 16-Bit-Pow! möglich, dann muß aber mit den Pixeln im
Bildspeicher gearbeitet werden.
| ColorPlane |
Open
SetForeColor(r,g,b)
Dot
WriteStr |
Zeichenebene öffnen
Vordergrundfarbe setzen
Punkt zeichnen
Zeichenkette ausgeben |
| File |
Open
ReadBlock
WriteBlock
WriteChar
Close |
Datei öffnen
Datum lesen
Datum schreiben
einzelnes Byte schreiben
Datei schließen |
| Strings |
Str |
Wandlung Zahl -> String |
| WinUser * |
GetActiveWindow, ShowWindow |
zum automatischen Maximieren des Fensters (kann weggelassen werden) |
Didaktische Bemerkung: Das Anzeigen eines großen Bildes in ColorPlane kann
sehr lange dauern. Natürlich kann man auch ein schnelles Windows-Programm
schreiben, aber dann geht die Einfachheit der Arbeit mit ColorPlane verloren.
Im Unterricht sollte es aber nicht das Ziel sein, die SEHR aufwendigen Windows-Programme
zu schreiben, das sollte Delphi überlassen werden. So erzielt man mit dem
einfachen ColorPlane sehr einfach überraschende
Ergebnisse.
* Das Einbinden von WinUser erfordert die Aufnahme der Datei win32.lib in
das Projekt:

4. Die Programme
Das Programm lädt ein im aktuellen Verzeichnis stehendes Bild und zeigt
es sowie einige seiner Daten an.
Es beginnt mit dem Festlegen der Variablen:
Es folgt das Einlesen der Daten:
Hierbei ist darauf zu achten, daß das aktuelle Verzeichnis bekannt ist.
Anderenfalls kann man auch den absoluten Pfad angeben. Die Daten können
jetzt wahlweise als INTEGER oder als LONGINT direkt mit BlockRead gelesen
werden:
(Auszug)
Das Bild selbst wird - etwas großzügig, zugegeben - im Ganzen in das
Array gelesen:
Die Datei wird geschlossen:
Die Angaben zum Bild werden mit WriteStr ausgegeben:
Die Ausgabe der Bilddaten erfolgt nun zeilenweise von links nach rechts und von
unten nach oben. Die linke untere Ecke kann frei auf dem Bildschirm plaziert
werden. Nach jeder Zeile ist die Korrektur auf durch 4 teilbare Breite zu vollziehen
(s. 2. ):
Dieses Programm soll demonstrieren, wie ein Pow!-Programm von der DOS-Kommandozeile
aufgerufen wird.
Nach dem Aufruf wird eine Datei F.BMP (je nach Programmtext) geladen, invertiert
und als INV.BMP gespeichert. Bemerkenswert ist, daß hier die Verwendung
des Moduls File ausreicht.
Das Ergebnis läßt sich in Paint bewundern:
Als Vorlage für den Namen diente das unerreichte Programm gimp,
das freie Gnu Image Manipulation Program.
Es stellt eine Benutzeroberfläche zum Laden, Speichern und Verändern
von Bildern zur Verfügung.
Das Bild wird wie in ladebild.mod in das Array
bild geladen. Objekt der Veränderung sind die jeweils 3 Bytes eines jeden
Bildpunktes. Nachdem die Mechanismen zum Laden und Anzeigen bekannt sind, kann
nun reiche Ernte mit sehr einfachen Algorithmen
eingefahren werden.
Invertieren
Ein Bildpunkt wird invertiert, indem seine Farbwerte im Wertebereich 0..255 gespiegelt
werden:
Kontrast verringern (flauer)
Der Helligkeitswert jedes Farbbytes wird halbiert und um den Farbmittelwert
gruppiert:
Kontrast verstärken (kontrastreicher)
Der Helligkeitswert jedes Farbbytes wird um 64 gesenkt und anschließend
verdoppelt. Falls die Berechnung aus 0..255 herausführt, wird korrigiert:
Man sieht sehr gut, daß die letzten beiden Operationen nicht zueinander
invers sind. Beim Verringern des Kontrasts gehen Daten verloren. Scannersoftware
beugt diesem Effekt vor, indem deutlich mehr Bits pro Pixel als zum Anzeigen
nötig eingelesen werden.
Ausgangsbild - flauer - kontrastreicher - kontrastreicher - flauer:




Schwarzweißbild erzeugen
Beim Schwarzweißbild - besser Graustufenbild - werden die rgb-Werte gemittelt
und der Mittelwert gleichmäßig auf r, g, und b verteilt:
mittelwert ist dabei ein CHAR.
5. Resümee
Mit etwas Geduld beim Erforschen des Bitmap-Formates kann man sehr schöne
Effekte beim Bearbeiten von Bildern mit dem eigenen Programm erzielen.
Es sind Anwendungen der Themen
- Schleifen
- Datentypen, Typwandlung
- Dateien
- Grafik
in reichem Maße vorhanden. Das sichtbare Ergebnis auf dem Bildschirm ist
Ansporn für die Schüler (und für den Lehrer).
Literatur
Geiß/Geiß: Vom Anfänger zum GEM-Profi.
Hüthig Buch Verlag Heidelberg 1991
Günter Born: Referenzhandbuch Dateiformate. Addison-Wesley
1995 (3. Auflage)