SDL: Farbwert aus Surface auslesen



  • Hallo,

    ich möchte Tile Abschnitte bestimmen können, in dem ich die relatieve Pixelposition des Cursors auf ein Surface übertrage. Nun beschafft mir eine Funktion die rgb werte des Pixels an dieser Stelle.

    Nun mein Problem:

    Wenn ich in der Funktion das Surface "screen" angebe, welches so initialisiert wurde:

    SDL_Surface *screen;
    screen = SDL_SetVideoMode(800, 600, 32, 0);

    funktioniert alles.

    Wenn ich aber ein Surface angebe, das so initialisiert wurde:

    SDL_Surface *refTile;
    refTile = SDL_LoadBMP("C:/Sicherung/STUFF/PROJEKTE/SDL_Tiles/tiles/tref.bmp");

    stimmen die Farbwerte nicht mehr überein.

    Ich glaube es ist eher unwichtig ob nun verstanden wird, was das mit dem ganzen Vergleichen soll, das funktioniert auch schon wunderbar, ABER eben nur beim "Hauptvideodenster" NICHT bei einer "normalen" Surfacevariable.

    Ich weiss nicht wie speziell meine Frage ist, ich hoffe dennoch das mir wer helfen kann.

    Thx schonmal.



  • Ich wette tref.bmp hat nicht das pixelformat, das du erwartest. Evtl n bug in der funktion, die dir RGB-Werte liefert oder Konvertierungsungenauigkeiten. Genauere Antwort oder bessere Vermutung kann ich ohne code nicht liefern.



  • das ist der code der die pixel informationen beschafft:

    ////
    Uint32 get_pixel32( SDL_Surface *surface, int x, int y )
    {
    //Convert the pixels to 32 bit
    Uint32 *pixels = (Uint32 *)surface->pixels;
    //Get the requested pixel
    return pixels[ ( y * surface->w ) + x ];
    }
    ////

    ich rufe das dann so auf:

    ////
    Uint32 pix;
    SDL_PixelFormat *fmt;
    Uint8 r;
    Uint8 g;
    Uint8 b;
    Uint8 bpp;
    fmt = screen->format;
    bpp = screen->format->BitsPerPixel;
    SDL_LockSurface(screen);
    pix = get_pixel32(screen, x, y);
    SDL_UnlockSurface(screen);
    SDL_GetRGB(pix, fmt, &r, &g, &b);
    ////

    tref.bmp hat 24Bit Bittiefe

    Wenn ich allerdings auf "screen" blitten lasse, und dann die abfrage auf die betreffende Stelle von "screen" mache, geht es. Damit will ich sagen das dort zumindest die Bittiefe egal zu sein scheint.



  • SDL_Blitsurface führt automatisch eine pixelkonvertierung durch, das 24 bit rgb wird dadurch problemlos zu 32 bit rgba konvertiert.

    Uint32 *pixels = (Uint32 *)surface->pixels;

    Das funktioniert natürlich mit einer 24-Bit surface nicht, denn da is ein pixel eben nur ein "Uint24" sozusagen.
    Sagen wir mal, du hast 3 24-Bit pixel:
    1.:FF00FF
    2.:00FF00
    3.:FFFFFF
    Sieht im Speicher so aus:

    FF00FF00FF00FFFFFF

    Liest du jetzt den 2. pixel aus (Uint32->4 byte nach rechts):
    FF00FF00 überspringst du
    FF00FFFF kommt als pixelinformation raus (rot is FF, grün 00, blau FF) - anders als eben das "richtige" 00FF00

    Entweder schreibst du die RGB-auslese funktion also "richtig", dass sie mehrere Formate verwenden (also erst Format auslesen und davon abhängig die Farbinformationen) oder du arbeitest nur mit 32-bit surfaces (z.B. beim laden einer BMP mit hilfe von CreateRGBSurface eine 32 bit surface erstellen und mit BlitSurface draufkopieren)

    Nebenbei, man sollte surface->pitch verwenden statt surface->w, weil prinzipiell padding bytes eingefügt werden können (die man mit surface->pitch dann richtig überspringt, mit surface->w aber nicht)

    Pitch gibt die Anzahl der bytes an, bis eine neue Zeile anfängt.



  • Vielen Dank für die ganzen Antworten.

    Ich habe das Problem gelöst, in dem ich eine 32bit bitmap mit gimp erstellt hab.

    Dennoch werde ich mir mal zur Verständnisserweiterung ne Funkion machen, die aus allen Formaten lesen kann.

    Vielen Dank nochmal, einfach ein geiles Forum


Anmelden zum Antworten