Buchempfehlung
Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie
Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie
Umfassend, aber leicht verständlich führt dieses Buch in die Programmierung von ATMEL AVR Mikrocontrollern ein. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Code-Beispiel

Code-Beispiele » Grafik und Fonts

Grafiken für die PNG-Kompression optimieren

Lizenz:Erster Autor:Letzte Bearbeitung:
WTFPLRedakteurJojo 11.02.2011

Viele Webgrafiken und auch Grafiken für Spiele und ähnliche Programme liegen heute im PNG-Format vor. Auch wenn die Anzahl der Modem-Surfer wohl so langsam gegen null geht, sollte man gerade im Web auf verträgliche Dateigrößen achten. Niemand wartet freiwillig zehn Sekunden, bis eine Webseite inklusive Bilder geladen ist. Um PNG-Grafiken möglichst klein zu machen, gibt es Programme wie Externer Link!PNGOut, die unter anderem mit Bruteforce-Algorithmen kleinstmögliche PNG-Dateien zu erstellen versuchen. Dies geschieht in der Regel verlustfrei, das heißt das Bild wird zwar kleiner, sieht aber immer noch exakt wie das Original aus.

Offensichtlich kann man da noch mehr rausholen. Da 200kb einfach zu viel für eine Headergrafik waren, suchte ich nach möglichst unscheinbaren Möglichkeiten, TrueColor-Bilder so zu verändern, dass die PNG-Kompression kleinere Dateien erzeugen kann. Da wenige häufig auftretende Werte sich besser komprimieren lassen als viele selten auftretende Werte, wählte ich den Ansatz, die Least Significant Bits der RGB-Kanäle einfach wegzustreichen. Bei vielen Grafiken ist der Unterschied - sechs statt acht Bit pro Farbkanal in meinem Fall - überhaupt nicht offensichtlich. Das merkt man eigentlich nur bei extrem sanften Farbverläufen. Trotzdem konnte ich im Beispielfall die Dateigröße auf 125kb drücken - ordentlich!

Lange Rede, kurzer Sinn: Hier ist ein Code, der eine BMP-Datei lädt, die zwei LSBs aller Farbkanäle nullt und dann ein neues BMP rausschreibt. Die PNG-Umwandlung muss danach manuell vorgenommen werden, z.B. mit PNGOut.

' Bitte anpassen
#Define filename_in "in.bmp"
#Define filename_out "out.bmp"

Dim As UShort bmpw, bmph
Open filename_in For Binary As #1
    Get #1, 19, bmpw 'Breite des Bitmaps
    Get #1, 23, bmph 'Hoehe des Bitmaps
Close #1

ScreenRes bmpw, bmph, 32, 1, -1 ' Screen ohne grafisches Feedback erzeugen
Dim As Any Ptr img = ImageCreate(bmpw, bmph)

BLoad filename_in, img

For x As Integer = 0 To bmpw - 1
    For y As Integer = 0 To bmph - 1
        Dim As Integer pnt = Point(x, y, img)
        pnt = pnt And &HFFFCFCFC ' Bitmaske. Alphakanal bleibt vollständig erhalten (FF), Rot, Gruen und Blau werden jeweils um die untersten beiden Bits beschnitten (FC).
        PSet img, (x, y), pnt
    Next
Next

BSave filename_out, img

ImageDestroy img

Zusätzliche Informationen und Funktionen
  • Das Code-Beispiel wurde am 11.02.2011 von RedakteurJojo angelegt.
  • Die aktuellste Version wurde am 11.02.2011 von RedakteurJojo gespeichert.
  Bearbeiten Bearbeiten  

  Versionen Versionen