[XLib] Bild im Fenster darstellen (Refresh-Problem)



  • Hallo c-community,

    ich habe eine Frag zu XLib und wie ich ein Bild richtig und regelmäßig darstellen kann.

    Zuerst einmal möchte ich sagen, dass der prinzipielle Ablauf für mich klar ist. Ich öffne ein Fenster mit XCreateSimpleWindow und stelle es mit XWindowMap dar. Dies funktioniert auch.
    Probleme habe ich aber noch richtig zu verstehen, wie ich XCreateImage, XPutImage und XNextEvent richtig verwende, damit ich keinen Fehler wie:

    X error of feiled request: BadMatch (invalid parameter attributes)

    erzeuge und nicht im XNextEvent (blockiert Schleife) stecken bleibe.

    Ok jetzt mal etwas Quellcode für meine Schleife:

    while(1)
    {
        char* Image = V4LCamera_Get_Image(XWindow->V4LCamera)  // gibt das Bild zurück
        XImage* xImage = XCreateImage(XWindow->display, XWindow->visual, 8, ZPixmap, 0, XWindow->V4LCamera->fmt.fmt.pix.width, XWindow->V4LCamera->fmt.fmt.pix.height, 8, XWindow->V4LCamera->fmt.fmt.pix.bytesperline);  // was bedeutet die bitmap_pad????
        XPutImage(XWindow->display, XWindow->window, DefaultGC(XWindow->display, 0), xImage, 0, 0, 0, 0, XWindow->V4LCamera->fmt.fmt.pix.width, XWindow->V4LCamera->fmt.fmt.pix.height);
        XNextEvent(XWindow->display, &XWindow->event);
    }
    

    Bisher bekomme ich beim ausführen des Quellcodes den oben angeführten Fehler (Compilieren ist Fehlerfrei) und selbst bei dargestelltem Bild würde XNextEvent blocikieren. wie kann ich dieses Problem lösen?

    Zur Kamera Format ist 640 x 480. BytesPerLine sind 1280 (also 2 Byte pro Pixel).

    MfG
    mirrowwinger



  • [UPDATE]

    Also das Blockieren des Programmes habe ich jetzt wie folgt abgewendet:
    Ich verwende nicht mehr XNextEvent sondern XCheckIfEvent. Diese "schaut" ob ein passendes Event vorliegt. Da es mich einige Zeit beschäftigt hat, bis ich die Lösung gefunden (und verstanden) hatte, möchte ich hier eine Lösung für das Event "ButtonPress" und das Schließen des Fensters präsentieren:

    run = true;
    while (run)
    {
        char* Image = V4LCAMERA_Get_Image(XWindow->V4LCamera);
        // Bilddarstellung noch offen
        mem_free(Image);
        if(CheckIfEvent(XWindow->display, &XWindow->event, XWINDOW_PredicteXCheckIfEvent, (char*)XWindow))
        {
            switch(XWindow->event.type)
            {
                case ButtonPress:
                    printf("mouse button pressed!\n");
                    break;
                case ClientMessage:
                    run = false;
                    break;
                default:
                    // nothing
                    break;
            }
        usleep(200);
        }
    }
    }
    

    Die XWINDOW_PredicteXCheckIfEvent-Funktion:

    Bool    XWINDOW_PredicteXCheckIfEvent(display, event, arg)
    Display* display;
    XEvent* event;
    char* arg;
    {
        switch(event->type)
        {
            case ButtonPress:
            case ClientMessage:
                return True;
                break;
            default:
                return False;
                break;
        }
    }
    

    Einziges Problem scheint noch zu sein, dass das Fenster schneller Schließt, als ich (anscheinend) meinen ganzen Speicher frei geben kann. Es werden mit Valgrind immer 936 bytes in 5 blocks bemängelt. Da die reachable blocks aber bisher statisch immer die gleiche Größe haben, gehe ich davon aus, dass es kein schwerwiegendes Problem ist.

    [NOCH OFFEN]
    OK ich habe jetzt einiges probiert und folgende Situation erreicht:
    Ich kann Bilder aus der Kamera lesen und kurzzeitig im Fenster darstellen. Nach wenigen Sekunden bricht XLib ab mit einem Fatal-Error:

    XIO: fatal IO error 14 (Bad address) on X server "0:0"
    after 132 requests (12 known processed) with 5 events remaining

    Folgenden Quellcode habe ich verwendet:

    char* Image = V4LCAMERA_Get_Image(XWindow->V4LCamera);
    XImage* xImage = XCreateImage(XWindow->display, XWindow->visual, DefaultDepth(XWindow->display, XWindow->screen), ZPixmap, 0, Image, Width, Height, 8, 0);
    XPutImage(XWindow->display, XWindow->window, DefaultGC(XWindow->display, 0), xImage, 0, 0, 0, 0, Width, Height);
    XDestroyImage(xImage);
    mem_free(Image);
    XFlush(XWindow->display);
    

    Habe ich etwas übersehen, dass den "fatal error" auslöst? Komisch ist auch das Fenster wird mit der Width und Height des Bildes initialisiert. Trotzdem sind mehrere Bilder im Fenster (in der kurzen Zeit die es funktioniert) sichtbar (so 5 x 3 Bilder). Vieleicht kann hier ja jemand mal helfen.

    Vielen Dank
    mirrowwinger



  • [UPDATE]

    Also ich habe anscheinend erstmal das Grundproblem gelöst. Mit folgendem Quellcode wird das Bild angezeigt:
    (Das Ausgangsbild ist monochrom, weswegen eine Konvertierung nach SRGB notwendig ist)

    run = true;
    while (run)
    {
        char* Image = V4LCamera_Get_Image(XWindow->V4LCamera)  // gibt das Bild zurück
        char* RGBImage = XWINDOW_Convert_Monochrom2SRGB(XWindow, Image);
        free(Image);
        XImage* xImage = XCreateImage(XWindow->display, XWindow->visual, 8, ZPixmap, 0, RGBImage, XWindow->V4LCamera->fmt.fmt.pix.width, XWindow->V4LCamera->fmt.fmt.pix.height, 8, XWindow->V4LCamera->fmt.fmt.pix.bytesperline * 4);
        XPutImage(XWindow->display, XWindow->window, XWindow->gc, xImage, 0, 0, 0, 0, XWindow->V4LCamera->fmt.fmt.pix.width, XWindow->V4LCamera->fmt.fmt.pix.height);
        XDestroyImage(xImage);
        XSync(XWindow->display);
        if (XCheckIfEvent(...)
        ...
    }
    

    Für die noch vorhandenen Probleme wie die auf 1/4 geschrumpfte Größe des Bildes werde ich einen neuen Thread auf machen.

    MfG
    mirrowwinger


Anmelden zum Antworten