|
Linux-Projekte
für den Raspberry Pi
(in Python)
[Hardcopy
vom monochromen LCD-Inhalt erstellen (.gif)]
|
Das
war der erste, schwierigere Teil.
Diese LZW
Rohdaten müßen nun noch 'gepackt' werden:
Die
einzelnen Werte der GIF Rohdaten stehen ja nun mit
unterschiedlichen Bitlängen (2, 5, 6,...., 10, 12) in einer
Zwischendatei(oder in einer Variablen).
Damit in der
GIF-Enddatei kein Platz verschwendet wird, werden im Prinzip alle
Bits aneinandergehängt und in Blöcke mit je 8 Bits aufgeteilt
und wir haben - wen wunderts - Bytes, die ohne Zwischenraum in
die GIF-Datei geschrieben werden können.
Hab
mal wieder versucht das Ganze verständlich, grafisch
darzustellen:
(Der Einfachheit halber sind die Werte mit
unterschiedlichen Bitlängen schon aneinandergehängt)
|
|
Die
bereits LZW-Codierten Werte werden aneinandergehängt und vom
Dateianfang her
ein “Fenster“ mit 8 Bit
darübergelegt
|
|
|
Diese
8 Bit (1 Byte) sind dann die Grundlage zur
'Paketierung')
Aus Wert 1, 2 und 3 ergibt
sich das Ergebnis 0A (1. Byte)
|
|
|
Der
Eingabestrom wird nun um 8 Bits nach rechts verschoben
(gekürzt)
Wert 3, 4 und 5 werden im „Fenster“
herausgefiltert
Das Ergebnis ist 26 (2. Byte)
|
|
|
Der
Eingabestrom wird erneut um 8 Bits nach rechts verschoben
(gekürzt)
Wert 5, 6 und 7 werden im „Fenster“
herausgefiltert
Das Ergebnis ist 2F (3. Byte)
|
So
geht das weiter, bis alle vorher bei der LZW-Codierten erzeugten
Werte verarbeitet sind.
Im Falle, daß beim allerletzten
Wert nicht mehr genügend Bits vorhanden sind um das „Fenster“
zu füllen, wird dieses von links her mit Nullen
aufgefüllt.
Das war's nun schon. Allerdings
erst mit Teil 2.
Jetzt
werden die so gewonnenen Daten noch in Blöcke à maximal 255
Byte aufgeteilt
Auch
hier mal wieder eine Grafik:
|
|
Ganz
zu Anfang steht die Bitlänge
Minimum, die wir als 'Bitanzahl' bereits von der
LZW-Codierung kennen
Dann
folgen die realen Datenblöcke (1 bis N), die sich dann auch
in der GIF-Datei wiederfinden.
Jeder Block besteht aus:
der
Angabe der Anzahl der
Folgebytes
(Nutzdaten). Es können MAXIMAL 255 Bytes sein
Die
tatsächlichen Datenbytes folgen (wie gesagt, maximal 255 -
NICHT eingerechnet ist das Byte mit der Anzahl der
Folgebytes!)
Sind
keine weiteren Daten mehr vorhanden, folgt der Abschluß mit
der Folgebytelänge 0
(Zahl Null)
|
Kurz
war er, der dritte Teil.
Aber keine Angst, JETZT wird das
Ganze nur noch ausgegeben und abgespeichert.
ALLERDINGS
muß dabei natürlich das entsprechende Datei-Format eingehalten
werden.
Dazu
auch hier wieder eine grafische Darstellung:
|
|
Der
Header besteht aus
Signatur und Version
GIF + [87a oder 89a]
Logischer
screen descriptor: Erzeugt eine ' virtuelle'
Prohjektionsfläche/ zeigt, ob eine Globale Farbtabelle
vorhanden ist/ setzt Hintergrundfarbe und das
Seitenverhältnis/ . . .
Die Globale
Farbtabelle enthält die Werte für Rot, Grün und Blau
für jede notwendige Farbe in der max. 256 Einträgen großen
Indextabelle
Image
descriptor enthält:
die Bildposition auf der
Projektionsfläche
Bildhöhe und Breite
eine
Markierung für Zeilensprung
gibt an, ob es eine lokale
Farbtabelle gibt
. . .
|
|
Doch
noch ein Hinweis zu den Farbtabellen:
Bei der GIF
Codierung werden nicht die Werte (Rot/ Grün/ Blau) für jedes
Pixel verarbeitet (auch Schwarz/ Weiß wird mit Rot/ Grün/
Blau erzeugt)), sondern jede Farbe mit ihren 3 Farbwerten wird
in eine Tabelle eingetragen und jeder Eintrag erhält eine
laufende Nummer. Gleiche Farben werden durch die gleiche
Nummer repräsentiert. Eine Tabelle kann maximal 256
Farbeinträge haben. Daher ist bei einem Einzelbild bei GIF
die Farbanzahl auf 256 beschränkt!
Bei der Codierung
werden die 'Farbnummern'' verarbeitet, NICHT die 3 FarbWerte!
(Spart jede Menge Speicherplatz)
|
|
|
Die
locale Farbtabelle
enthält die Werte für Rot, Grün und Blau für jede
notwendige Farbe in der max. 256 Einträgen großen
Indextabelle.
Entweder die Globale oder die Lokale
Farbtabelle muß vorhanden sein.
Bilddaten
werden in Blöcken á max. 255 Byte abgelegt. Diese Blöcke
werden solange hintereinander abgespeichert, bis alle Rohdaten
untergebracht sind.
Am Ende der Bilddaten
folgt der BlockTerminator
Der
Trailer ist die
Markierung für 'Dateiende erreicht'
|
Das
war's also, die Geschichte der GIF-Kodierung. Nun nur noch
die Daten in der richtigen Reihenfolge auf die SD-Karte in eine
Datei geschrieben und ENDE.
Eigentlich hatte ich
mir das Ganze doch einfacher vorgestellt und bis das Programm
soweit fertig war, daß es einigeermaßen funktionierte, hat es
etliche Monate (natürlich mit Unterbrechungen) gedauert. Dafür
kann ich mir nun, wenn es notwendig ist, die LCD-Darstellung am
'großen' Bildschirm ansehen, sie ausdrucken oder per Mail
verschicken.
Das Programm ist zunächst nur für das
monochrome LC-Display entwickelt worden. Zwischenzeitlich habe
ich aber auch ein farbiges Display erworben und darauf
verschiedene, neue Grafiken angezeigt. Farbe und Schwarz/Weiß
unterscheiden sind aber in dern Ausgangsdaten (Rasterdaten)
erheblich. Daher mußte ich für das Farbdisplay eine eigene
Programmvariante entwickeln. Diese wird hier nicht vorgestellt.
Einer Zusammenführung beider Versionen ist geplant, aber noch
nicht in Arbeit.
Um an
alle Informationen über das GIF-Dateiformat und vor allem die
LZW-Codierung und das Packen zu kommen, mußten VIELE Stunden im
Internet recherchiert werden. Dabei waren etliche Dokumente nur
in englischer Sprache vorhanden, [verdammt] schwer zu finden oder
sehr unübersichtlich, so daß es geraume Zeit gedauert hat, die
für die GIF-Erzeugung erforderlichen Informationen alle
zusammenzutragen und dann auch noch zu verstehen. =8-[ Hab dabei
das Ganze oft 'in die Ecke gefeuert' und Tagelang liegen lassen,
wenn ich nicht weitergekommen bin. Dieser
Link hat bei mir dann maßgeblich zum Verständnis
beigetragen.
Leider wird in allen mir bekannten Beispielen
nicht näher auf die variable Bitlänge bei der LZW-Codierung
eingegangen. DAS
mußte
ich mir - auch wieder - MÜÜÜÜÜHHHHSAM erarbeiten.
Die
GIF, bzw. LZW (Lempel-Ziv-Welch) Codierung ist patentiert. Der/
die Rechteeigentümer sind bei der Einhaltung anscheinend nicht
zimperlich gewesen. So ist im WEB nachzulesen, daß die Rechte
zur Verwendung wohl 1.000 US$/ 5.000 US$ (hier sind sich die
Berichte nicht einig) oder mehr betragen und große Firmen sich
zum Teil vor Gericht verantworten mussten.
Gerüchten
zufolge wurden auch schon Privatpersonen belangt.
Dieses
Patent ist wohl inzwischen abgelaufen
und der Algorithmus kann frei verwendet werden.
Sollte es
anderweitige Informationen dazu geben, wäre ich über einen
entsprechenden Hinweis dankbar, damit die notwendigen Schritte
eingeleitet werden könnten!
Meine
Python-Kenntnisse waren zum Zeitpunkt dieses Projektes noch nicht
so weit entwickelt, so daß sich im Programm 'LCDcopy' mit
Sicherheit noch etliche Teile befinden, die verbessert werden
können bezüglich Laufzeit, Programmieralgorythmus und
objektorientierter Programmierung.
Nichtsdesdotrotz:
das Programm läuft fehlerfrei und erstellt von dem
programminternen Bildschirmpuffer Kopien als GIF-Dateien. Dabei
werden nur die absolut notwendigen Daten gespeichert, keine
Kommentare, Copyrights, Erweiterungen, etc. Es dauert pro Kopie
zwar ca. 6 Sekunden (Pi 2), aber die Datei wird korrekt
abgespeichert und kann durch Standardprogramme wieder angezeigt
werden.
Damit
man die LCD-Kopien auch einigermaßen am normalen Bildschirm und
auch auf einem eventuellen Ausduck entziffern kann (240 x 128
Pixel sind dort ja nicht sonderlich groß), habe ich noch einen
'Multiplikator' in das Programm eingebaut. Damit kann sowohl die
X-Richtung, als auch die Y-Richtung unabhängig vergrößert
werden (1,2,3,...). Das ist natürlich nur bis zu einem
bestimmten Faktor sinnvoll!
Eine Datei in
Originalgröße, mit Multiplikator 1 (X und Y)
Im
Gegensatz dazu dann ein paar vergrößerte Beispiele:
|
Darstellung der
Daueraufzeichnung eines HomeMatic Temperatursensors
|
Balkendiagramm mit
Differenzauswertung verschiedener HomeMatic Sensoren gegen
zwei Außentemperaturen (sehr praktisch im Sommer!)
|
|
Darstellung
des 16-tägigen Temperaturverlaufs von www.wetter.com
(Ursprünglich waren es 14 Tage, daher die überzähligen
Balken)
|
Anzeige
der Daueraufzeichnung (alle 2 Sekunden) eines SPI
Luftdrucksensors
|
|
Anzeige
der optischen Impulse des Stromzählers über eine
HomeMatic-Sensor (mit angeschlossener PV-Anlage und
Stromspeicher)
|
Anzeige der EDL-SML Daten
des 2-Richtungs-Stromzählers (aktuelle Wirkleistung) mit
angeschlossener PV-Anlage und Stromspeicher
|
Es
fällt natürlich auf, daß verschiedene Grafiken breite, weiße
Ränder aufweisen. Das rührt daher, daß diese Grafiken
ursprünglich für kleinere Displays entwickelt wurden und noch
nicht an das große EA
DOGXL240-7 Display angepaßt wurden. Dazu fehlte bisher
leider die Zeit, da meistens irgendwelche neue, interessante
Projekte dazwischenkommen ;-)
Einigen aufmerksamen
Lesern mag aufgefallen sein, daß in der Darstellung der
Bildschirmkopie farbige Skalenlinien auftauchen und sich deshalb
fragen: Farbige Linien auf eine monochromen LCD-Display? Wie geht
das denn????
Gute Frage! Aber die Antwort ist genauso
einfach:
Bei der Grafikerstellung wurden Grautöne des
Displays verwendet (und DORT auch dargestellt). Diese wurden bei
der Codierung ins GIF-Format in der dazugehörenden Farbtabelle
nicht als Grau codiert, sondern in der nun sichtbaren Farbe. Wird
die GIF-Datei 'von Hand' erstellt, ist das kein Problem (ein
Rechner [Computer] macht immer das und zwar genau nur das, was
man ihm sagt)!