title logo
title right side
30.01.2026 15:16:57 Lokal:
Serverstatus: (1.16/1.91/1.8729.67/1265 GByte  
Aussentemperatur : 2.5 °C  Luftdruck : 999.94 hPas/mbar
Impressions: 13 
Visits heute: 237 

  Aktuelle Seite: SDL2 jpeg viewer

Go SSL ...Home  

Minimalistischer JPEG-Viewer mit SDL2 in C

Dieses Projekt demonstriert, wie man mit der SDL2-Bibliothek unter Linux ein performantes Programm schreibt, das JPEG-Bilder lädt, sie intelligent an die Bildschirmgröße anpasst und auf Benutzereingaben reagiert.

Features:

  • JPEG-Unterstützung: Nutzt SDL2_image für moderne Bildformate.

  • Intelligente Skalierung: Bilder werden automatisch auf maximal 80 % der Monitorauflösung skaliert, wobei das Seitenverhältnis erhalten bleibt.

  • Flexible Steuerung: Schließen des Fensters per Mausklick, durch die Taste q oder ESC.

  • Kommandozeilen-Argumente: Der Pfad zum Bild wird beim Start einfach übergeben.

Abhängigkeiten installieren

Bevor du den Code kompilieren kannst, müssen die Entwicklungsbibliotheken von SDL2 auf deinem System installiert sein. Unter Debian-basierten Systemen (wie Ubuntu oder Linux Mint) geht das mit:

Bash

sudo apt update
sudo apt install build-essential libsdl2-dev libsdl2-image-dev

Der Quellcode (SDLjpgview.c)

Der folgende Code übernimmt das Ressourcen-Management, die Event-Verarbeitung und das Rendering.

C

#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>

/**
 * Ein einfacher Bildbetrachter basierend auf SDL2.
 * Erlaubt das Anzeigen von JPEGs mit automatischer Skalierung.
 */

int main(int argc, char* argv[]) {
    // Prüfung der Kommandozeilenargumente
    if (argc < 2) {
        fprintf(stderr, "Benutzung: %s <Pfad_zum_Bild>\n", argv[0]);
        return 1;
    }

    // SDL2 Video-Subsystem initialisieren
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        fprintf(stderr, "SDL konnte nicht initialisiert werden: %s\n", SDL_GetError());
        return 1;
    }

    // SDL2_image für JPEG-Unterstützung initialisieren
    int imgFlags = IMG_INIT_JPG;
    if (!(IMG_Init(imgFlags) & imgFlags)) {
        fprintf(stderr, "SDL_image konnte nicht initialisiert werden: %s\n", IMG_GetError());
        SDL_Quit();
        return 1;
    }

    // Bild laden, um die Originalmaße zu erhalten
    SDL_Surface* tempSurface = IMG_Load(argv[1]);
    if (!tempSurface) {
        fprintf(stderr, "Bild konnte nicht geladen werden: %s\n", IMG_GetError());
        IMG_Quit();
        SDL_Quit();
        return 1;
    }

    // Bildschirmauflösung abfragen für intelligente Skalierung
    SDL_DisplayMode dm;
    SDL_GetCurrentDisplayMode(0, &dm);

    int winW = tempSurface->w;
    int winH = tempSurface->h;
    float maxW = dm.w * 0.8f; // Maximal 80% der Bildschirmbreite
    float maxH = dm.h * 0.8f; // Maximal 80% der Bildschirmhöhe

    // Seitenverhältnis beibehalten
    float scale = 1.0f;
    if (winW > maxW || winH > maxH) {
        float scaleW = maxW / winW;
        float scaleH = maxH / winH;
        scale = (scaleW < scaleH) ? scaleW : scaleH;
    }

    winW = (int)(winW * scale);
    winH = (int)(winH * scale);

    // Fenster und Hardware-beschleunigten Renderer erstellen
    SDL_Window* window = SDL_CreateWindow("SDL2 Viewer - 'q', 'ESC' oder Klick zum Beenden", 
                                          SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 
                                          winW, winH, SDL_WINDOW_SHOWN);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

    // Textur aus der Surface erstellen und Speicher der Surface freigeben
    SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, tempSurface);
    SDL_FreeSurface(tempSurface);

    int quit = 0;
    SDL_Event e;

    // Hauptschleife (Event-Loop)
    while (!quit) {
        while (SDL_PollEvent(&e) != 0) {
            // Beenden bei X-Button, Mausklick oder speziellen Tasten
            if (e.type == SDL_QUIT || e.type == SDL_MOUSEBUTTONDOWN) {
                quit = 1;
            } else if (e.type == SDL_KEYDOWN) {
                if (e.key.keysym.sym == SDLK_ESCAPE || e.key.keysym.sym == SDLK_q) {
                    quit = 1;
                }
            }
        }

        // Bild zeichnen
        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, texture, NULL, NULL);
        SDL_RenderPresent(renderer);
    }

    // Ressourcen sauber freigeben
    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    IMG_Quit();
    SDL_Quit();

    return 0;
}

Automatisierung mit dem Makefile

Um das Kompilieren zu vereinfachen, nutzen wir ein Makefile. Es verwendet sdl2-config, um die korrekten Pfade für Header und Bibliotheken auf deinem System automatisch zu finden.

Erstelle eine Datei namens Makefile im selben Ordner:

Makefile

# Variablen
CC = gcc
CFLAGS = -Wall -Wextra -std=c11 $(shell sdl2-config --cflags)
LIBS = $(shell sdl2-config --libs) -lSDL2_image
TARGET = SDLjpgview
SRC = SDLjpgview.c

$(TARGET): $(SRC)
                $(CC) $(CFLAGS) $(SRC) -o $(TARGET) $(LIBS)

# Aufräumen
clean:
                rm -f $(TARGET)

.PHONY: all clean

# Standard-Ziel
all: $(TARGET)

Kompilierung und Benutzung

Öffne dein Terminal im Projektordner und folge diesen Schritten:

  • Programm kompilieren:

Bash

make
  • Programm ausführen: Gib den Pfad zu einem beliebigen JPEG-Bild an:

Bash

./SDLjpgview pfad/zu/deinem/bild.jpg

Steuerung:

Mausklick: Schließt das Fenster.

Taste 'q' oder 'ESC': Schließt das Fenster.

X-Button: Beendet das Programm.

Was könnte man noch hinzufügen?

Dieses Programm ist eine solide Basis. Für zukünftige Versionen könnte man folgende Features implementieren:

Unterstützung für weitere Formate wie PNG oder WebP (einfach über IMG_INIT_PNG etc.).

Blättern durch alle Bilder eines Ordners mit den Pfeiltasten.

Echte Vollbildanzeige per Tastendruck.

Lizenz

GPL V3 oder neuer

Download

Format tar.xz LINK
Format 7z LINK