Satyria

Bilder anzeigen und speichern

In diesem Kapitel möchte ich ein Bild anzeigen lassen. Als Grundprogramm verwenden wird den Sourcecode „2.5.c„.

Da wir bereits ein Fenster anzeigen lassen konnten, werden wir dies nun einfach mit der Anzeige eines Bildes erweitern. Es gibt hierzu eine zusätzliche Bibliothek, SDL_Image, die wir dazu verwenden werden.
SDL selbst benötigt dazu einen Renderer. Dies ist eine Struktur, die viele Informationen über das Bild enthält, die SDL intern benötigt. Diese hängt an dem Fenster, welches wir erzeugt haben. Da wir diese Struktur später für vieles brauchen, legen wir dies global an. Das gleiche machen wir auch für das Bild, welches wir anzeigen möchten. Dieses wird allerdings in eine Texture abgelegt

Während der Initialisierung müssen wir noch ein paar Dinge tun. Zunächst initialisieren wir SDL_Image, da wir ein Bild laden wollen und diese Bibliothek uns hier in vieler Hinsicht unterstützt. Dies machen wir direkt nach der SDL-Initialisierung.

Damit der entsprechende Renderer da ist, müssen wir ihn mit CreateRender() mit Bezug auf unser Fenster erstellen.

Damit haben wir schon das System soweit vorbereitet und kommen auf das laden des Bildes.
Dazu erstellen wir zunächst eine neue Funktion „LadeBild“. In dieser Funktion laden wir das Bild mit der Funktion IMG_LoadTexture() und geben ihr das Ziel (bild) mit den Infos aus renderer und den Dateinamen an. Wenn es nicht funktioniert hat, wird NULL zurückgegeben und wir geben eine Fehlermeldung raus.

Kommen wir nun zum main(). Nach der Initialisierung laden wir zunächst das Bild. Danach wird es mit SDL_RenderCopy in den renderer kopiert und mit SDL_RenderPresent angezeigt. Das war es schon.

Sourcecode: 3.c
Bild: blume.png

Das Kompilieren des Programms

Da wir nun hier eine neue Bibliothek verwenden, müssen wir es beim Kompilieren auch angeben, dass es so ist. Dies wird mit diesem Aufruf gemacht:

gcc -o 5.exe 5.c -Ic:/msys64/mingw64/include -Lc:/msys64/mingw64/lib -lmsys-2.0 -lSDL2_image -lSDL2main -lSDL2 -mwindows

oder hier 32-Bit:

gcc -o 5.exe 5.c -Ic:/msys32/mingw32/include -Lc:/msys32/mingw32/lib -lmsys-2.0 -lSDL2_image -lSDL2main -lSDL2 -mwindows

Übrigens: Jetzt können Bilder in den Formaten: GIF, JPG, LBM, PCX, PNG, PNM, TGA, TIF, XCF, XPM und XV mit den entsprechenden Funktionen geladen werden.

Das Speichern eines Bildes

Da SDL eigentlich für die Programmierung von Spielen erstellt wurde, gibt es von SDL selbst nur ein speichern in unkomprimierten BMP-Format. SDL_Image bietet hier mehr Formate an, welches ich hier mal beschreibe. Nachteil ist immer der, dass es nur „Screenshots“ sind und wenig mit Grafikprogrammen zu tun hat. Aber wenigstens gibt es dazu einen Weg.

Wenn wir die Funktionen „IMG_Save…“ anschauen, benötigen wir ein surface. Dies ist eine alte Methode, die unter SDL1 Verwendung fand. SDL2 unterstützt es weiterhin, aber hier im Kurs haben wir nur Renderer und Texturen benutzt. Also brauchen wir ein Surface, auf dem die Pixel des Bildes abgelegt sind. Zunächst erzeugen wir mit SDL_CreateRGBSurfaceWithFormat ein entsprechendes Surface, welches unserem Fenster entspricht. Danach kopieren wir die Daten aus dem Renderer in dieses Surface mit SDL_RenderReadPixels. Jetzt sind die Daten dort, wo wir sie auch brauchen und können es mit z.B. IMG_SavePNG abspeichern.

Sourcecode: 3.5.c
Bild: blume.png

Als JPG speichern

Auch hier werden wir von SDL_Image unterstützt und wir verwenden die Funktion IMG_SaveJPG. Diese können wir einfach für IMG_SavePNG ersetzen. Allerdings wird hier ein weiterer Parameter übergeben, der die Komprimierung angibt. Dieser bedeutet bei einem Wert von 100, keine Komprimierung und je kleiner der Wert wird, um so höher wird sie. Allerdings verliert das Bild seine Qualität.

Sourcecode: 3.6.c
Bild: blume.png

<< Übersicht | < Das erste Programm | Zeichnen >

Das erste Programm

Mit diesem Tutor möchte ich Euch ein wenig das SDL (Simple DirectMedia Layer) Programmieren zeigen. Wie ich bereits zuvor geschrieben habe, benutzen wir hierfür eine Windowsumgebung und MSYS2.
Aber fangen wir gleich an, damit wir auch was sehen, hier das erste Beispiel:

Sourcecode: 1.c

Kompiliert wird es mit:

gcc -o 1.exe 1.c -Ic:/msys64/mingw64/include -Lc:/msys64/mingw64/lib -lmsys-2.0 -lSDL2main -lSDL2 -mwindows

und ausgeführt wird es mit:

./1

Bei diesem Programm wird ein SDL-Fenster für 2000 Millisekunden geöffnet.

Zunächst muss man den Kompiler mitteilen, welche Header benötigt werden. die geschieht mit #include <SDL2/SDL.h>. Danach definiere ich zwei Konstanten, die mir die Fenstergröße festlegen. Der globale Variable fenster wird das SDL_Window zugewiesen. Diese wird später das Fenster beherbergen. Da C alle Funktionen bekannt sein müssen, wird hier die Funktion Initialisierung() bekannt gemacht. Was darin steht, kommt später.

Im eigentlichen Hauptprogramm (main) steht dann allerdings relativ wenig. Zunächst wird die Funktion der Initialisierung ausgeführt und anschließend wird mit SDL_Delay 2000 Millisekunden gewartet. Danach wird das Programm beendet.

In der Funktion Initialisierung() steht da schon mehr. Zunächst muss man SDL Initialisieren, damit überhaupt SDL funktioniert. Dies geschieht mit SDL_Init. Hier wird noch angegeben, was wir den von SDL benötigen. In unserem Fall einfach nur die Grafikfunktion. Allerdings werden auch Events initialisiert, aber hierzu später.

Wenn es schief ging, wird eine Fehlermeldung herausgegeben. SDL_GetError gibt uns sogar einen genaueren Grund an, warum es nicht ging.

Mit SDL_CreateWindow wird dann das Fenster erzeugt, welches wir hier dann sehen. Der Funktion werden der Titelname, die Position und die Eigenschaft des Fensters übergeben.

Auch hier wird eine Fehlermeldung herausgegeben, wenn das Fenster nicht erzeugt werden konnte.

Reagieren auf eine Eingabe

Na ja, eigentlich kann man dieses Programm nicht wirklich als gut bezeichnen. Ein Fenster wird geöffnet und dann irgendwann wieder geschlossen.

Wir machen es nun ein bisschen spannender und reagieren zumindest mal auf das Schließsymbol.
Dazu müssen wir eine Abfrage erstellen, die dann entsprechend reagieren kann. Statt mit SDL_Delay auf das Ende zu warten, setzen wir hier eine neue Funktion ein, die wir einfach mal Eingabe() nennen. Da es zu fast unendlich vielen Eingaben kommen kann und wir alles irgendwie verarbeiten müssen, machen wir hier noch eine While-Schleife darum:

Unsere Eingabe()-Funktion hat folgendes aussehen:

Zunächst benötigen wir hier eine SDL_Event Variable, die wir event nennen. Dort werden die „Events“ abgelegt, wenn es welche gibt.

In der while-schleife fragen wir mit SDL_PoolEvent die Warteschleife der Events ab und legen das Ereignis nach &event. Über switch(event.type) fragen wir dann dieses Event ab.

Zunächst reagieren wir nur auf „SDL_QUIT„, was das schließen des Fensters bedeutet und beenden das Programm.

Sourcecode: 2.c

Programm sauber beenden

Das Programm, welches bisher geschrieben wurde, ist bisher sehr einfach geschrieben worden. Damit aber ein SDL-Programm sauber läuft, sollten noch ein paar Dinge beachtet werden.

Am Anfang des Programms wird SDL Initialisiert und sperrt einige Ressourcen des Betriebssystems. Wird Das Programm allerdings nicht sauber beendet, wird dem Betriebssystem einige Ressourcen nicht zurückgegeben. Bei den heutigen Rechnern ist das kleine Programm noch kein Problem, aber wenn diese größer werden, kann es irgendwann zu Problemen führen. Deshalb werden wir dieses Programm etwas verändern und die entsprechenden Ressourcen, auch bei einem Fehler, wieder dem System zurückgeben.

Wie gesagt, wird zunächst SDL Initialisiert und anschließend ein Fenster geöffnet. Wenn es nun beim Fenster öffnen zu einem Fehler kommt, müssen wir die Initialisierung wieder rückgängig machen. Dies geschieht ganz einfach mit SDL_Quit(). Also nach dem öffnen des Fensters ändern wir die Fehlerbehandlung:

Unser Loop, also unser Eingabefunktion, hat nun einen gravierenden Fehler. Es ist eine Endlosschleife, wenn es da nicht diesen harten Ausgang hätte…
Aber hier müssen wir auch irgendwie reagieren, wenn das Programm geschlossen wird. Dies sollte im Hauptprogramm „main()“ erfolgen. Dazu schreiben wir unseren Loop um. Allerdings müssten wir hier noch aus der Eingabe-Funktion wissen, ob nun das Programm beendet werden soll. Dazu ändern wir zunächst diese Eingabe-Funktion, mit der Möglichkeit, dass wir Werte daraus zurückgeben:

Zunächst setzen wir die Variable „done“ auf „0“. Diese Zahl halten wir, solange das Programm, oder später eventuell kein Fehler, passierte. Mit return(done) geben wir diesen Code zurück.
Wenn nun das Fenster geschlossen wird, wird done mit 1 belegt und am Ende dann per return(done) zurückgegeben.

In unserem Hauptprogramm fragen wir genau diesen Wert ab:

Auch hier verwenden wir eine Variable „done„. Die Schleife wird sooft wiederholt, wie done = 0 ist. Sobald die Funktion Eingabe eine 1 zurückgibt, wird done mit 1 belegt und die Schleife beendet.
Jetzt können wir dem System nun alles freigeben. dies geschieht mit SDL_DestroyWindow und SDL_Quit.
Unser Programm wird beendet

Sourcecode: 2.5.c

< Übersicht | Bilder anzeigen und speichern >

SDL Programmierung (Start)

Vorab: Es wäre schön, wenn Ihr einen Link auf www.satyria.de in Euren Projekten hinterlasst und eventuell mir per E-Mail (SDL@satyria.de) bescheid gebt. Über jedes Interesse daran würde mich freuen.

Ich selbst beschreibe es hier in einer Windowsumgebung. Wie wir GCC und SDL zum Programmieren einrichten, beschreibe ich unter SDL-Biblothek unter Windows. Dies installiert MSYS2, welches wir hier verwenden. Es kann aber auch relativ einfach nach Linux portiert werden. Wie diese Sourcen auszusehen haben und wie hier Kompiliert wird, beschreibe ich unter SDL für Linux.

Über SDL

Simple DirectMedia Layer ist eine plattformübergreifende Entwicklungsbibliothek, die über OpenGL und Direct3D Zugriff auf Audio-, Tastatur-, Maus-, Joystick- und Grafikhardware auf niedriger Ebene bietet. Es wird von Videowiedergabesoftware, Emulatoren und beliebten Spielen verwendet, einschließlich Valves preisgekröntem Katalog und vielen Humble Bundle– Spielen.
SDL unterstützt offiziell Windows, Mac OS X, Linux, iOS und Android. Unterstützung für andere Plattformen finden Sie im Quellcode.
SDL ist in C geschrieben, funktioniert nativ mit C ++ und es sind Verbindungen für mehrere andere Sprachen verfügbar, einschließlich C # und Python.
SDL 2.0 wird unter der Lizenz zlib vertrieben . Mit dieser Lizenz können Sie SDL in jeder Software frei verwenden.

Übersetzt aus http://libsdl.org/

Besser kann man das eigentlich nicht beschreiben!

Inhalt

Weitere Infos erhaltet Ihr bei: http://de.wikibooks.org/wiki/SDL oder https://wiki.libsdl.org

Das Tool html2one

Dieses Tool setzt meherere HTML-Dateien zu einer HTML-Datei zusammen.

Download: DOS (auch Windows) Version: html2one.zip
Download: Linux Version: html2oneL.zip

GCC unter Windows installieren (alt)

Bitte verwendet die neue Installationsanleitung (MSYS2 installieren). Diese Version hier ist grundsätzlich weiterhin verwendbar, aber um alle hier auf dieser Seite beschriebenen Anleitungen zu verwenden, sollte MSYS2 installiert sein.

Installation von GCC unter Windows

GCC kann unter Windows inzwischen relativ einfach installiert werden. Ich selbst verwende hier MinGW.
MinGW bietet einen Installer (mingw-get-setup.exe) dazu an „http://sourceforge.net/projects/mingw/files/Installer/“.
Dieser wird zunächst von der Seite geladen und anschließend ausgeführt.

(mehr …)

« Zurückblättern