Forum: Mikrocontroller und Digitale Elektronik Bitmaps Komprimierung


von Christian (Gast)


Lesenswert?

Hi,

So nachdem ich nun mit meinem LPC2103 Board von Phillips mein Oled
Display von Osram 128x128 korrekt ansteuere hab ich nun ein Problem mit
der Grösse der Bitmaps.
Bisher sind meine Bitmaps ca. 115x78 Pixel gross, würd nun aber gerne
ein 128x128 grosses Bitmap anzeigen lassen.
Problem ist mein 32kb Flash Speicher.
128*128*3=49152 byte
Jeder Pixel braucht 3 bytes...da 262k Farben.

Was könnte ich nun machen?
1. Die Bitmap komprimieren. Mittels RLE? Oder irgendeinem Verfahren
wies ein Packer macht? Dann müsste mein Controller das Bild wieder
dekomprimieren.
2. Auf ein anderes Format umsteigen? Ne jpg? Aber ich hab mir gestern
die Source zum jpeg runtergeladen und die 85 c Sourcen sind mir etwas
zuviel.
3.Gibts ne Möglichkeit das Bild auf der Festplatte des PCs zu speichern
und dann über USB Pixel nach Pixel zu zeichnen? Also lesen des 1. Pixel
dann zeichnen auf dem Display und 2. Pixel lesen und zeichen. Dann sind
ja immer nur 24bit im Speicher.
4. Wie schwer, kompliziert wäre es ein Speicher an das Board zu hängen?
z.B. USB-Stick oder SD Karte oder was sonst noch so gibt.
Bin was Hardware angeht nicht der Experte ;) Und hab noch ca. 2 Wochen
Zeit mich mit dem ganzen zu Beschäftigen.

Fällt sonst noch jemand was ein?

Gruss Chris

von A.K. (Gast)


Lesenswert?

Trivialerweise benötigst du für 16K Pixel keine 16M Farbcodes. Per
Bildanalyse sollten sich die Bilder auf 256 genutzte Farben aus einem
64K-Farbraum reduzieren lassen.

Damit sind's nur noch 128x128x1 + 256x2 = ~17KB.

RLE sollte das noch weiter reduzieren.

von Karl heinz B. (kbucheg)


Lesenswert?

> Jeder Pixel braucht 3 bytes

Das muss aber nicht so sein. Such mal nach Möglichkeiten
wie du ein Palette erzeugen kannst. Eine Palette ist
eine Lookup Table, die für ein Byte die RGB Werte enthält.
Im Bild belegt jedes Pixel nur ein Byte. Die effektiven
RGB Werte erhält man, indem man mit dem Byte aus dem Bild
in diese Palette geht.

Das GIF-Format arbeitet zb auf diese Art.

(128 * 128 Pixel macht 16384. Plus die 256 * 3Bytes von der Palette
 macht dann 17152 Bytes fürs Bild).

> da 262k Farben.

Dein Bild hat grade mal 16384 Pixel insgesammt. Also können nicht
mehr als 16k Farben gleichzeitig vorkommen. Ausserdem ist es mehr
als unwahrscheinlich, dass tatsächlich jedes einzelne Pixel
eine andere Farbe als alle anderen hat. -> 256 Farben sind meist
ausreichend. Wenns dann immer noch Farbsprünge gibt, kann man
versuchen mittels 'Dithering' da noch was zu machen.

von Wolfram (Gast)


Lesenswert?

reichen dir nicht 256 Farben mit optinierter Farbtabelle?
Das wären 128*128*1Byte.
Wenn es richtig bunt wird bringt Dir RLE nicht so richtig etwas.
3. ja aber wahrscheinlich zu langsam wenn du Pixel fuer Pixel machst,
wenn dann blockweise
4. SD Karte kein Problem, aber wenn du vor den JPG Sourcen
zurückschreckst wird das bei den FAT Sourcen wahrscheinlich nicht
anders sein.

von Rolf Magnus (Gast)


Lesenswert?

> Jeder Pixel braucht 3 bytes...da 262k Farben.

Dann ist es keine Bitmap, aber das nur am Rande.
Du könntest vielleicht ein Indexformat benutzen, also z.B. 8 Bit pro
Pixel, und dann in einer Lookuptabelle (Palette) festlegen, welcher
Wert welcher Farbe entsprechen soll. Dann mit einem üblichen
Grafikprogramm die optimale Palette ausrechnen lassen. Mußt halt mal
schauen, ob die darzustellenden Bilder damit noch gut genug aussehen.
RLE ist eine recht einfache Kompression, die aber nur dann gut
funktioniert, wenn du größere einfarbige Flächen hast. jpeg ist zu
kompliziert für so einen kleinen µC. Andere Komprimieralgorithmen
müssen oft während der Dekomprimierung Tabellen aufbauen, brauchen also
zumindest während dieser Zeit auch signifikant Speicher.
Du könntest dir die Kompressionsverfahren für Texturen in
3D-Beschleunigern anschauen. Das alte FXT1 von 3Dfx ist glaube ich
relativ einfach aufgebaut. Wie komplex die neueren Verfahren wie S3TC
sind, weiß ich nicht.

von Harry (Gast)


Lesenswert?

Naja, Dein Controller hat einfach zu wenig Speicher. Mit so ner
mickrigen Speichergröße ein Farbgrafikdisplay ansteuern zu wollen ist
eine Schnapsidee. Wenns wirklich nicht anders geht dann nimm ein
externes EEPROM für die Grafikdaten, 24AA512 mit 64kB oder wenns mehr
sein darf ein Atmel DataFlash mit bis zu 8MB.

Der C64 hatte mit 64kB RAM aus gutem Grund nur 16 Farben.

von Christian (Gast)


Lesenswert?

Öhm ich hab glaub vergessen zu erwähnen das der Controller auf dem OLED
Display entweder 65k Farben oder 262k Farben braucht.

Also muss dem beim 65k Modus folgende Farbinformation übergeben.
Bitmuster: RRRR RGGG GGGB BBBB
Bei 262k Farben
Bitmuster: xxRR RRRR
           xxGG GGGG
           xxBB BBBB
x für dont Care und R=Rot,G=Grün und B=Blau

Also ich weis ja nicht aber man kann doch sagen umso mehr Farben umso
"schöner" wird mein Bild dargestellt oder stimmt diese Aussage etwar
nicht?
Ziel ist einfach mal herauszufinden wie gut das Display ist.

Das mit der Lookup Tabelle find ich ne gute Idee.

Also ich hab gerade ein 65k Bild dargestellt und das sieht deutlich
schlechter aus als n 262k Bild...
Die Kontraste sind eben viel besser...

von Christian (Gast)


Lesenswert?

Da hab ich doch vergessen mein Beitrag abzusenden...
@Harry
ja das musst du mir nicht sagen, dass das eine Schnappsidee ist. War
nicht meine Idee ;) aber ich hab nunmal das Board neben mir liegen.

Das mit ner Palette überleg ich mir mal.

von Karl heinz B. (kbucheg)


Lesenswert?

Spricht ja auch nichts dagegen, dass dein Controller
so ne grosse Farbtiefe haben will. Nur musst du das Bild
halt nicht mit dieser Farbtiefe im µC Speicher halten.
Im µC Speicher hast du ein paletiertes Bild und wenn
du es zum Controller schickst, bläst du es auf.
Kein Mensch sagt, dass du im Hauptspeicher und im Controller
dieselben Bytes haben musst.

von Karl heinz B. (kbucheg)


Lesenswert?

> Also ich hab gerade ein 65k Bild dargestellt und das sieht deutlich
> schlechter aus als n 262k Bild

Logo.
Mit 6 Bit pro Grundfarbe hat man halt keine vernünftige
Farbabstufung.

von Trinken (Gast)


Lesenswert?

Du kannst dein Bild auch in den FourierRaum transformieren, und die
Randfrequenzen abschneiden. Dann dieses Frequenzbild speichern
(komprimiert, da viele Frequenzen nacheinander vorkommen). Zum Anzeigen
dekomprimieren, und in den Bildraum zurücktransformieren.

Eine FFT geht schnell, und du mußt für den Standardfall nur eine Zeile
im Arbeitsspeicher halten.

von Wolfram (Gast)


Lesenswert?

nur so nebenbei:
ein 256Farben Bild mit Palette hat in den 256 Paletteneinträgen 262K,
aus VGA Tradition.
mit 128*128 komme ich auf 16384 maximal gleichzeitig mögliche Farben
auf dem Display.
Ein ordentliches Grafikbearbeitungsprogramm sollte mit optimierter
Farbpalette und Dithern ein Ordentliches Bild hinbekommen.
Ausserdem frage ich mich, wofür du dir über das ganze so viele Gedanken
machst. Ein Foto wo du wirklich so viele Farben bräuchtest, sollte eine
ganz andere Auflösung als 128x128 haben. Was auch immer du auf dem
Display für Bilder anzeigst, die Farbauflösung dürfte nicht wirklich
dein Problem sein.

von Christian (Gast)


Lesenswert?

@Wolfram
Ok dann kann ich mit Photoshop z.B. ein Bitmap abspeichern das eine
Grösse von 16kb hat und ne Grösse von 128x128?
Zurzeit stell ich das Wallpaper mit der Wüste und Mond von WindowsXP
dar.(Wüstenmond.jpg)
Wie soll ich das Bild dann abspeichern?
Oder noch besser kannst du mir ein schönes Kontrastreiches Bild geben
mit 128x128 und der Grösse?

FFT, och nö das hab ich in Mathe gehasst :) aber ich werds mir mal
merken.

Und ja das Bild komprimieren und dann Pixel für Pixel oder Zeile für
Zeile dann erst aufblähen und zeichnen hab ich ja vor....

Und danke für eure zahlreichen Antworten!

von Karl heinz B. (kbucheg)


Lesenswert?

Photoshop

Du bearbeitest das Bild zuerst auf die richtige größe
und beauftragst dann Photoshop eine Palette zu erstellen:
Bild / Modus -> indizierte Farben.

Danach speicherst du das Bild als BMP ab. BMP ist einfacher
zu lesen als GIF.

Mal ein Beispiel im Anhang (Hätte ich gerne gesendet, aber
BMP ist nicht erlaubt).

von Hauke Radtki (Gast)


Lesenswert?

zippen :>

von Christian (Gast)


Lesenswert?

oh wow!
nur noch 17kb das Bild! Dankeschön.
Jetzt versteh ich das. Ich dachte die Tabelle muss ich mir selber
zusammenbasteln.
Nun muss ich eben bevor ich das Pixel zeichnen will in die Farbtabelle
schauen und die richtige Farbinfo rauslesen oder?

Muss ich morgen mal schauen ob ich das hinbekommen.

Danke nochmal!

Gruss und schönen Abend

von Karl H. (kbuchegg)


Lesenswert?

> Jetzt versteh ich das. Ich dachte die Tabelle muss ich mir selber
> zusammenbasteln.

Die Palette wird selbstverständlich mit dem Bild gespeichert
und ist integrierter Bestandteil der Datei.

> Nun muss ich eben bevor ich das Pixel zeichnen will in die
> Farbtabelle schauen und die richtige Farbinfo rauslesen oder?

Jetzt hast du den Dreh raus.

von Christian (Gast)


Lesenswert?

Naja so ganz hab ich den Dreh doch nicht raus.
Erstmal da gibts n paar Einstellungen beim Speichern. Was soll ich
auswählen? Bild/Modus Indizierte Farben:
System Windows: Sieht man deutlich Qualitätsverluste und das wäre mir
zu schlecht das Bild.
Ich würde Lokal(Selektiv) nehmen. Seh ich keinen Unterschied.
Genauso bei allen Lokal und Master. Was ist hier der Unterschied?
Farben sind immer 256.
Erzwungen? Keine?Primärfarben?
Bei Optionen alles aus oder?

Ok schau ich mir das neue File nun an und vergleich das mit dem Header
aus wikipedia seh ich da wenig Übereinstimmung.

Hier der Header und ein bißchen von den Farbinfos:
Ist n 128x128 Bild 8bit,256 Farbenpalette
Lokal(Selektiv) Erzwungen Primärfarben
Option keine

42 4D 38 44 00 00 00 00 00 00 36 04//0.byte=biSize 00 00 28 00
00 00 80 00 00 00 80 00 00 00//14.byte=biBitCount 01 00 08 00 00 00
00 00 00 00 00 00 12 0B 00 00 12 0B//32.byte 00 00 00 00
00 00 00 00 00 00 FF FF FF 00 00 FF FF 00 FF 00
FF 00 00 00 FF 00 FF FF 00 00 00 FF 00 00 FF 00
00 00 00 00 00 00 FA FF FE 00 97 96 A2 00 06 05
0C 00 0F 0E 13 00 90 8D 94 00 8A 86 8B 00 9A 96
9B 00 0A 06 0A 00 FE FA FE 00 75 74 75 00 6F 6E
6F 00 94 92 93 00 03 02 02 00 12 0D 0D 00 93 8D
8D 00 FE FA FA 00 FA F6 F6 00 F2 EE EE 00 80 7F
7F 00 8B 85 84 00 B8 AE AC 00 9A 96 95 00 A2 9D
9B 00 7B 79 78 00 75 6D 68 00 83 7B 76 00 61 5C
59 00 56 4F 4A 00 6B 63 5D 00 7A 74 6F 00 61 58
50 00 6B 68 65 00 A4 A3 A2 00 3B 32 28 00 4A 43
3B 00 88 83 7D 00 AC A7 A1 00 8E 8A 85 00 94 92
8D 00 9C 9B 95 00 0B 0B 06 00 22 22 21 00 FE FE

Header aus wiki:
http://de.wikipedia.org/wiki/Windows_bitmap

Dann ist mein 14.Byte NULL und ich hab ne Farbtiefe von 0 oder was isn
nu los?
Da muss doch irgendwo in der Nähe 08 stehen!?

Und meine Farbtabelle seh ich auch nicht.
Das müsste ja so grob das hier sein:
00 00 00 00 00 00 FF FF FF 00 00 FF FF 00 FF 00
FF 00 00 00 FF 00 FF FF 00 00 00 FF 00 00 FF 00
00 00 00 00 00 00 FA FF FE 00

von Karl heinz B. (kbucheg)


Lesenswert?

> System Windows: Sieht man deutlich Qualitätsverluste und das wäre
> mir zu schlecht das Bild.
> Ich würde Lokal(Selektiv) nehmen. Seh ich keinen Unterschied.
> Genauso bei allen Lokal und Master. Was ist hier der Unterschied?
> Farben sind immer 256.

Im ersten Fall wird eine Standardpalette genommen. D.h. die
256 Farben sind bereits vorgegeben und das Bild wird mit
in diese vorgegebene Palette hineingerechnet.

Im zweiten Fall wird die Palette extra für dieses Bild
angepasst. D.h. die Palette wird auf das Bild abgestimmt
und nicht umgekehrt.

von AxelR. (Gast)


Lesenswert?

man könnte doch auch die Farbanzahl bestimmen lassen. Dann hat die
Farbtabelle nur soviele Einträge, wie tatsächlich nötig oder macht das
"den Brei nicht fett"?
Sehr interessantes Thema, abo *g*

AxelR.

von Karl heinz B. (kbucheg)


Lesenswert?

Ich weiss nicht was du hast, ist doch alles da

42 4D 38 44 00 00 00 00 00 00 36 04 00 00 28 00
00 00 80 00 00 00 80 00 00 00 01 00 08 00 00 00
00 00 00 00 00 00 12 0B 00 00 12 0B 00 00 00 00
00 00 00 00 00 00 FF FF FF 00 00 FF FF 00 FF 00
FF 00 00 00 FF 00 FF FF 00 00 00 FF 00 00 FF 00
00 00 00 00 00 00 FA FF FE 00 97 96 A2 00 06 05
0C 00 0F 0E 13 00 90 8D 94 00 8A 86 8B 00 9A 96
9B 00 0A 06 0A 00 FE FA FE 00 75 74 75 00 6F 6E
6F 00 94 92 93 00 03 02 02 00 12 0D 0D 00 93 8D
8D 00 FE FA FA 00 FA F6 F6 00 F2 EE EE 00 80 7F
7F 00 8B 85 84 00 B8 AE AC 00 9A 96 95 00 A2 9D
9B 00 7B 79 78 00 75 6D 68 00 83 7B 76 00 61 5C
59 00 56 4F 4A 00 6B 63 5D 00 7A 74 6F 00 61 58
50 00 6B 68 65 00 A4 A3 A2 00 3B 32 28 00 4A 43
3B 00 88 83 7D 00 AC A7 A1 00 8E 8A 85 00 94 92
8D 00 9C 9B 95 00 0B 0B 06 00 22 22 21 00 FE FE

BITMAPFILEHEADER (Größe: 14 Byte)

bfType          WORD        42 4D               "BM"
bfSize          DWORD       38 44 00 00         0x00004438 = 17464
bfReserved      DWORD       00 00 00 00
bfOffset        DWORD       36 04 00 00         0x00000436 = 1078

BITMAPINFOHEADER (Größe: 40 Byte)

biSize          DWORD       28 00 00 00         0x00000028 = 40
biWidth         LONG        80 00 00 00         0x00000080 = 128
biHeight        LONG        80 00 00 00         0x00000080 = 128
biPlanes        WORD        01 00               0x0001     = 1
biBitCount      WORD        08 00               0x0008     = 8
biCompression   DWORD       00 00 00 00         0x0000     =
unkomprimiert
biSizeImage     DWORD       00 00 00 00         0x0000
biXPelsPerMeter LONG        12 0B 00 00
biYPelsPerMeter LONG        12 0B 00 00
biClrUsed       DWORD       00 00 00 00         0x0000     =
                                       maximale Farbe, bei
                                       biBitCount == 8 -> 256
biClrImportant  DWORD       00 00 00 00         0x000      = Palette
                                       ist vollständig

danach kommt die Palette als RGB Triplets, und zwar wie in
biClrUsed / brBitCount angegeben, 256 Stück

 FF FF FF                   R: 255, G: 255, B: 255
 00 00 FF                   R:   0, G:   0, B: 255
 FF 00 FF                   R: 255, G:   0, B: 255
 ...

gefolgt von den Bytes für die Pixel. Die Pixel müssten eigentlich,
wie in bfOffset angegeben, ab der Adresse 0x0436 anfangen.

von Karl heinz B. (kbucheg)


Lesenswert?

> Dann hat die Farbtabelle nur soviele Einträge, wie tatsächlich
> nötig oder macht das "den Brei nicht fett"?

Wie du schon sagst, das macht den 'Brei nicht fett'. Das Problem
liegt ja meist nicht in der Größe der Palette. Ob da jetzt
183 oder 256 RGB-Triplets (je 3 Bytes) drinnen sind ist für
die Dateigröße relativ egal. Bytes in den Pixeln sparst du auch
nicht (und das ist der Löwenanteil), da du nach wie vor pro
Pixel immer noch ein Byte brauchst. Selbst wenn du die Palette
auf unter 128 Einträge bringst, könnte man dann pro Pixel von
8 Bit auf 7 Bit runtergehen. Den Aufwand in der Decodierung in
diesem Fall brauch ich dir nicht beschreiben :-)

von Karl heinz B. (kbucheg)


Lesenswert?

> Ob da jetzt 183 oder 256 RGB-Triplets (je 3 Bytes) drinnen sind ist
> für die Dateigröße relativ egal.

Dazu kommt, dass die meisten bekannten Dateisysteme (*) ein
File ja sowieso nur in Blöcken allokieren können. Ob das
File jetzt 17823 Bytes hat oder 17748 Bytes ist vom Platzverbrauch
auf dem Medium völlig egal. Als Beispiel: es werden in beiden
Fällen 5 Stück 4096-Byte Sektoren verbraucht.

(*) zumindest kenne ich keines, was nicht heist dass es das
nicht gibt.

von Rolf Magnus (Gast)


Lesenswert?

Reiserfs kann einen Block zwischen mehreren Dateien aufteilen.

von Christian (Gast)


Lesenswert?

Ok klar hast Recht es ist alles da.
Das Byte für den Pixel den ich zeichnen will steht dann für die Adresse
der Farbe in der Farbtabelle

Also z.B 0x02 würd heisen:
FF FF FF 00  0x00
00 FF FF 00  0x01
FF 00 FF 00  0x02
00 00 FF 00  0x03
usw.
Dann hat das Pixel die Farbinfo FF 00 FF

Und es stimmt ja das hinter jeder Farbe ein Byte mit einer 0 kommt!?
Und sind nun die Farben nicht BGR?

Wenn ich ein Rotes Bitmap speicher dann stehen nur 0x03 drinne.
Und das wäre ja 00 00 FF

von Karl heinz B. (kbucheg)


Lesenswert?

> Und es stimmt ja das hinter jeder Farbe ein Byte mit einer 0 kommt!?
> Und sind nun die Farben nicht BGR?

An die Details kann ich mich nicht mehr so genau
erinnern. Einen Loader schreibt man meist nur einemal :-)
Ist bei mir schon lange her :-)

Wenn ich mir aber den HEX Dump so ansehe:
> Und es stimmt ja das hinter jeder Farbe ein Byte mit einer 0 kommt!?

<Kramen in der Erinnerung>
Das muesste der Alpha-Kanal sein (Transparenz).

> Und sind nun die Farben nicht BGR?
Ausprobieren. Aber so dunkel erinnert: du könntest recht haben.
Wie gesagt: ausprobieren ist hier die schnellste Möglichkeit.
Ein Kanalwechsel Rot-Blau ist nicht zu übersehen :-)

von Christian (Gast)


Lesenswert?

Ok dann Versuch ich mal das hinzubekommen.
Und das Bild das ich nun auf dem Bildschirm seh kommt nachher genauso
gut auf meine Display raus?

Dir dann vielen Danke für deine Mühen!

Gruss

von Christian (Gast)


Lesenswert?

Es geht!
Sieht echt noch super aus das Bild.
Danke du Genie ;)

von Lupin (Gast)


Lesenswert?

wo bekomme ich denn ein 128x128 OLED von OSRAM her? Bei reichelt gab es
ja nur ein 96x64 OLED oder so.

von Christian (Gast)


Lesenswert?

Also das hier hat die Fima in der ich arbeite umsonst bekommen. Für Test
Zwecke eben...
Keine Ahnung ob man das schon kaufen kann.

von S.M. (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Ich weiss nicht was du hast, ist doch alles da
>
> 42 4D 38 44 00 00 00 00 00 00 36 04 00 00 28 00
> 00 00 80 00 00 00 80 00 00 00 01 00 08 00 00 00
>
> BITMAPFILEHEADER (Größe: 14 Byte)
>
> bfType          WORD        42 4D               "BM"
> bfSize          DWORD       38 44 00 00         0x00004438 = 17464
> bfReserved      DWORD       00 00 00 00
> bfOffset        DWORD       36 04 00 00         0x00000436 = 1078
>
> BITMAPINFOHEADER (Größe: 40 Byte)
>
> biSize          DWORD       28 00 00 00         0x00000028 = 40
> biWidth         LONG        80 00 00 00         0x00000080 = 128
> biHeight        LONG        80 00 00 00         0x00000080 = 128
> biPlanes        WORD        01 00               0x0001     = 1
> biBitCount      WORD        08 00               0x0008     = 8
> biCompression   DWORD       00 00 00 00         0x0000     =
> unkomprimiert
> biSizeImage     DWORD       00 00 00 00         0x0000
> biXPelsPerMeter LONG        12 0B 00 00
> biYPelsPerMeter LONG        12 0B 00 00
> biClrUsed       DWORD       00 00 00 00         0x0000     =
>                                        maximale Farbe, bei
>                                        biBitCount == 8 -> 256
> biClrImportant  DWORD       00 00 00 00         0x000      = Palette



Hallo,
ich will jetzt keine neue Thema starten. Mich interessiert, wie ich 
diese Information aus einer 96x64pixel BITMAP raus bekomme. Wo finde ich 
diese ganze INFO aus einer *.bmp Datei.

Vielen Dank!

von Arne (Gast)


Lesenswert?

Meinst Du den Aufbau des Headers?
Der steht u.a. hier: http://de.wikipedia.org/wiki/Windows_Bitmap

von S.M. (Gast)


Lesenswert?

Arne schrieb:
> Meinst Du den Aufbau des Headers?
> Der steht u.a. hier: http://de.wikipedia.org/wiki/Windows_Bitmap

Ja das habe ich schon gesehen, Danke.
Ich meine wie kann ich mir  Header und die Farb-Tabelle in *.bmp File 
ansehen? konvertieren? mit einem Editor öffnen?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.