Wie kann ich einen TEXT Grafisch auf dem Zero W groß über den Screen schreiben?

  • Liebe Leute,

    meine ersten Erfahrungen mit Raspi Pi Zero W. Leider versuche ich krampfhaft ;( einen Text mit max. 20 Zeichen schön leserlich über den Ganzen Screen grafisch zu schreiben.

    Hier mein Ansatz. Bekomme anfangs Segmentation fault, doch mit debug info nicht mehr, was komisch ist.

    Hier anbei mein Code:

    Wäre um INFOs und Tipps Dankbar.

    :P

  • Wie kann ich einen TEXT Grafisch auf dem Zero W groß über den Screen schreiben?? Schau mal ob du hier fündig wirst!

  • In der Datei schreibd.c hast Du regelmäßig den Befehl close(fbfd); eingebaut. Das dürfte der Hauptgrund sein, warum das Programm nicht abstürzt.

    Baue mal in den Aufruf für den Compiler die Schalter -Wall und -Wextra ein, damit der Compiler strenger prüft.

    Edited once, last by peuler: -Werr ist falsch, korrekt ist -Wextra (March 9, 2025 at 10:57 PM).

  • Hallo, ok hab ich gemacht. Er compiliert mit diesen Problemen.

    er2.txt

    Habe nun die Warnings korrigiert,

    schreibd.c

    NUN kein segmentation fault mehr, doch sehe ich keinen TEXT.

    run2.txt

    Was kann man nun machen? Besten dank.


    Das meint AI dazu. Und danach korrigiert schreib4.c, doch leider sehe ich keinen TEXT immer noch nicht.

    • Code
      Es gibt mehrere Gründe, warum du den Text möglicherweise nicht sehen kannst:
      Farbe und Hintergrund: Du schreibst den Text mit weißer Farbe auf einen schwarzen Hintergrund. Wenn die Farben nicht korrekt gerendert werden, könnte der Text unsichtbar sein. Stelle sicher, dass die Farben korrekt sind und dass der Hintergrund tatsächlich schwarz ist.
      Positionierung: Der Text wird an einer bestimmten Position auf dem Bildschirm geschrieben. Wenn die Position außerhalb des sichtbaren Bereichs liegt, wirst du den Text nicht sehen. Überprüfe die Koordinaten, um sicherzustellen, dass der Text innerhalb des sichtbaren Bereichs geschrieben wird.
      Buchstabengröße: Die Buchstabengröße ist auf 20x20 Pixel festgelegt. Wenn die Buchstabengröße zu groß oder zu klein ist, könnte der Text nicht korrekt gerendert werden.
      Framebuffer-Konfiguration: Die Konfiguration des Framebuffers könnte falsch sein. Überprüfe die Ausgabe von vinfo.bits_per_pixel, um sicherzustellen, dass sie mit deiner Farbkonfiguration übereinstimmt.
      Textrendering: Du renderst den Text, indem du einfach weiße Pixel zeichnest. Dies ist kein echtes Textrendering, da es keine echte Schriftart oder -größe gibt. Für ein korrektes Textrendering müssten Schriftarten verwendet werden.

    Edited 5 times, last by wschrabi (March 10, 2025 at 5:54 AM).

  • wschrabi March 10, 2025 at 5:58 AM

    Added the label Debian 11 (Bullseye)
  • Wie willst du einen Text sehen wenn einfach weisse Pixel an die Position des Buchstabens geschrieben werden? Ich sehe nirgends einen Zugriff auf einen Font.

    Der Code ist auch sonst fragwuerdig weil er einfach annimmt dass ein Pixel 4 Bytes belegt. Schau mal nach was in vinfo.bits_per_pixel steht.

    In schreibd.c wird geprueft ob er ueber den Memoryblock hinausschreibt. Wahrscheinlich gibt es deshalb keinen Fehler.

  • Laut Textausgabe hast Du 16 Bit per Pixel. Dann aber Code der vier aufeinander folgende Bytes pro Pixel beschreibt, als wären das 32 Bit per Pixel im RGBA-Format. Das passt ja schon mal nicht. Und der Code macht auch einige annahmen über Bytes pro Pixelzeile, die virtuelle Auflösung und den Versatz in den den virtuellen Framebuffer die korrekt sein können, aber nicht müssen.

    “The object-oriented version of 'Spaghetti code' is, of course, 'Lasagna code'. (Too many layers)“ — Roberto Waltman

  • wschrabi Wie wichtig ist denn die genaue Grösse der einzelnen ”Pixel”? Denn man könnte grossen Text auch auf Ebene der Textkonsole lösen, in dem man ”Pixel” als Zeichen setzt, beispielsweise mit dem █ als ”Pixel” oder zwei davon (██) um ein eher quadratisches ”Pixel” zu erzeugen. Oder man arbeitet mit den drei Zeichen ▄, ▀, und █. Das sind dann keine 20×20 Grafikpixel-Blöcke sondern eher 16×16 wenn man zwei volle Blockzeichen nebeneinander setzt. Bildschirm löschen und Cursor positionieren geht über die üblichen ANSI-Escape-Sequenzen.

    Wenn man das nicht selbst ausprogrammieren möchte, wäre figlet oder toilet eventuell auch ein Programm, das man verwenden könnte.

    Falls der Framebuffer ein muss ist, würde ich da als erstes mal ein Programm schreiben, dass die ganzen relevanten Informationen ausgibt, dessen Ausgabe dann beispielsweise so aussehen könnte:

    Und dann darauf basierend ein Programm, das speziell auf diese Werte zugeschnitten ist, statt zu probieren etwas universelles zu schreiben, was mit beliebigen Framebuffern funktionieren würde. Das wird nämlich ziemlich aufwändig und testen kann man das ja auch nicht wirklich wenn man nicht auch die ganzen Varianten an Framebuffern zur Verfügung hat.

    Oder man sucht sich eine Bibliothek, die das für einen erledigt. Die „Simple Directmedia Layer“-Bibliothek (SDL) sollte beispielsweise mit dem Framebuffer arbeiten können.

    “The object-oriented version of 'Spaghetti code' is, of course, 'Lasagna code'. (Too many layers)“ — Roberto Waltman

  • Ich habe mal ein Interface für das HDMI-Display eines PI5 in c++ geschrieben. Den Text hab ich über Fontdateien eingebunden und mir Pixelweise darstellen lassen

    vielleicht hilft das weiter

    Jeder macht was er will, keiner macht was er soll, aber alle machen mit :)

  • Herzliche DANK

    Quote

    Die „Simple Directmedia Layer“-Bibliothek (SDL) sollte beispielsweise mit dem Framebuffer arbeiten können.

    :P

    Ich hab inzwischen das so gelöst.

    Dazu die LIbs laden.

    Code
     sudo apt install libcurl4-openssl-dev
     sudo apt install libsdl2-dev
     sudo apt install libsdl2-2.0-0 libsdl2-dev libsdl2-ttf-2.0-0 libsdl2-ttf-dev
     gcc --std=c11 -o hiddisok hiddisok.c -lSDL2 -lSDL2_ttf


    #include <SDL2/SDL.h>
    #include <SDL2/SDL_ttf.h>
    #include <stdio.h>
    #include <string.h>

    // Funktion zum Anzeigen eines Textes
    int DisplayTEXT(SDL_Renderer* renderer, TTF_Font* font, const char* text) {
    // Text rendern
    SDL_Color color = {255, 255, 255}; // Weißer Text

    // Text in eine Oberfläche rendern
    SDL_Surface *textSurface = TTF_RenderText_Solid(font, text, color);
    if (!textSurface) {
    printf("Fehler beim Rendern des Textes: %s\n", TTF_GetError());
    return 1;
    }

    // Oberfläche in eine Textur umwandeln
    SDL_Texture *textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
    if (!textTexture) {
    printf("Fehler beim Erstellen der Textur: %s\n", SDL_GetError());
    SDL_FreeSurface(textSurface);
    return 1;
    }

    // Fläche für den Text definieren
    SDL_Rect textRect = {100, 100, textSurface->w, textSurface->h};
    SDL_FreeSurface(textSurface);

    // Bildschirm löschen und Text zeichnen
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // Schwarzer Hintergrund
    SDL_RenderClear(renderer);

    // Text auf den Renderer kopieren und anzeigen
    SDL_RenderCopy(renderer, textTexture, NULL, &textRect);
    SDL_RenderPresent(renderer);

    // Warten
    SDL_Delay(5000); // Zeigt das Fenster für 5 Sekunden

    // Aufräumen
    SDL_DestroyTexture(textTexture);

    return 0;
    }

    int main() {
    // Initialisierung von SDL und SDL_ttf
    if (SDL_Init(SDL_INIT_VIDEO) != 0) {
    printf("Fehler beim Initialisieren von SDL: %s\n", SDL_GetError());
    return 1;
    }

    if (TTF_Init() != 0) {
    printf("Fehler beim Initialisieren von SDL_ttf: %s\n", TTF_GetError());
    SDL_Quit();
    return 1;
    }

    // Fenster und Renderer erstellen
    SDL_Window *window = SDL_CreateWindow("SDL_ttf Beispiel",
    SDL_WINDOWPOS_CENTERED,
    SDL_WINDOWPOS_CENTERED,
    640, 480,
    SDL_WINDOW_SHOWN);
    if (!window) {
    printf("Fehler beim Erstellen des Fensters: %s\n", SDL_GetError());
    TTF_Quit();
    SDL_Quit();
    return 1;
    }

    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    if (!renderer) {
    printf("Fehler beim Erstellen des Renderers: %s\n", SDL_GetError());
    SDL_DestroyWindow(window);
    TTF_Quit();
    SDL_Quit();
    return 1;
    }

    // Schriftart laden
    TTF_Font *font = TTF_OpenFont("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 24);
    if (!font) {
    printf("Fehler beim Laden der Schriftart: %s\n", TTF_GetError());
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    TTF_Quit();
    SDL_Quit();
    return 1;
    }

    // Text anzeigen
    const char* text = "Hallo Welt!";
    if (DisplayTEXT(renderer, font, text) != 0) {
    printf("Fehler beim Anzeigen des Textes.\n");
    }

    // Aufräumen
    TTF_CloseFont(font);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);

    TTF_Quit();
    SDL_Quit();

    return 0;
    }

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!