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:

      1. der Angabe der Anzahl der Folgebytes (Nutzdaten). Es können MAXIMAL 255 Bytes sein

      2. 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)!