SDL Get und Put Pixel Problem



  • Hey.
    habs ausprobiert, und bringt keinen unterschied, bekomme immer noch nur mull als farbwerte raus.

    Hier die Definition von Chars :

    struct Chars
    {
    	int		x;
    	int		y;
    	char	*smallChar;
    };
    

    Das Bild kann ich leider nicht anhängen.
    Ich habs mal hochgeladen. Ob man als ungergistrierter die links sehen kann weiß ich allerdings nicht :
    http://s7.directupload.net/file/d/2515/74zzieba_png.htm



  • Dein "pixels" ist 32 Bit, "pitch" stellt aber die Gesamtbreite der Surface in Byte dar:

    uchar *pixels= (uchar*)surface->pixels;
    uint *scanline= (uint*) (pixels + surface->pitch * y);
    uint color= scanline[x];
    


  • Mir is auch aufgefallen dass das unmöglich funktionieren kann was ich da geschrieben hab...

    Das von hellihjb sollte aber (endlich) stimmen.

    Nach meinen test bekomm ich als Werte nur 4294967295 (=0xFFFFFFFF) (weiß) 4278190080 (=0xFF000000) (schwarz) und 4278190335 (=0xFF0000FF) (rot) als Ausgabe. Einzige was ich geändert hab ist die angesprochene Berechnung in getpixel/putpixel (wenn auch in eigener, hässlicherer variante als die von hellihjb) . Da ich das bild nur als png speichern kann, hab ich das via SDL_Image als png geladen. Hm...



  • Noch ein großes "D'oh" - schwarz ist in sdl natürlich 0xFF000000, da deckend (opaque) afaik als FF alpha gewertet wird.

    if (pColor == 0)
    

    Wird also nie true.

    Mal der (bei mir) funktionierende code:

    #include <iostream>
    #include "SDL.h"
    #include "SDL_Image.h"
    using namespace std;
    
    	#if SDL_BYTEORDER == SDL_BIG_ENDIAN
    		const Uint32 RMASK = 0xff000000;
    		const Uint32 GMASK = 0x00ff0000;
    		const Uint32 BMASK = 0x0000ff00;
    		const Uint32 AMASK = 0x000000ff;
    	#else
    		const Uint32 RMASK = 0x000000ff;
    		const Uint32 GMASK = 0x0000ff00;
    		const Uint32 BMASK = 0x00ff0000;
    		const Uint32 AMASK = 0xff000000;
    	#endif
    
    SDL_Surface* g_pBackBuffer;
    SDL_Surface *pSur_Font;
    
    struct Chars
    {
        int        x;
        int        y;
        char    *smallChar;
    };
    
    Uint32 get_pixel32( SDL_Surface *surface, int x, int y )
    {
        //Convert the pixels to 32 bit
        void* target = (surface->pixels);
        char* tmp = reinterpret_cast<char*>(target);
        tmp+=y*(surface->pitch)+4*x;
        return *reinterpret_cast<Uint32*>(tmp);
        //Get the requested pixel
    }
    
    void put_pixel32( SDL_Surface *surface, int x, int y, Uint32 color )
    {
        //Convert the pixels to 32 bit
        void* target = (surface->pixels);
        char* tmp = reinterpret_cast<char*>(target);
        tmp+=y*(surface->pitch)+4*x;
        *reinterpret_cast<Uint32*>(tmp) = color;
    }
    
    void dawString (char *string,int xPos, int yPos, Uint32 color, int size)
    {
        int        j, i;
        int        x, y;
        int        w, h;
        int        k, l;
        int        s, d;
        bool    found = false ;
        int        len = strlen (string) ;
        int        charSize = 10 * size ;
        int        charSpacing ;
        Uint32 pColor;
    
        std::cout << "Zeichne string" << endl;
    
        pSur_Font = IMG_Load("74zzieba.png");
        //SDL_Surface *pSur_Font = IMG_Load_RW(SDL_RWFromFile("74zzieba.png", "rb"), 1);
        struct Chars pMyChars[] =
        {
        0,  0, "a",
        10, 0, "b",
        20, 0, "c",
        30, 0, "d",
        40, 0, "e",
        50, 0, "f",
        60, 0, "g",
        70, 0, "h",
        80, 0, "i",
        90, 0, "j",
        100, 0, "k",
        110, 0, "l",
        120, 0, "m",
        0, 10, "n",
        10, 10, "o",
        20, 10, "p",
        30, 10, "q",
        40, 10, "r",
        50, 10, "s",
        60, 10, "t",
        70, 10, "u",
        80, 10, "v",
        90, 10, "w",
        100, 10, "x",
        110, 10, "y",
        120, 10, "z",
        0, 20, " ",
        10, 20, "1",
        20, 20, "2",
        30, 20, "3",
        40, 20, "4",
        50, 20, "5",
        60, 20, "6",
        70, 20, "7",
        80, 20, "8",
        90, 20, "9",
        100, 20, "0",
        };
        int charAnz = (sizeof (pMyChars) / sizeof (pMyChars[0]));
    
        std::cout << "Anzahl aller möglichen zeichen : " << charAnz << endl;
    
        //SDL_LockSurface(g_pBackBuffer);
    
        for (j = 0 ; j < len ; j++) {       
            charSpacing = charSize * j ;
            for (i = 0 ; i < charAnz ; i++) {
                if (pMyChars[i].smallChar[0] == string[j]) {
                    found = true ;
                    x = pMyChars[i].x ;
                    y = pMyChars[i].y ;
                    std::cout << pMyChars[i].smallChar << endl;
                }
            }
            if (!found) {
                continue ;
            }
    
            w = 0 ;
            k = 0 ;
            while (w < charSize) {
                h = 0 ;
                l = 0 ;
                while (h < charSize) {
                    pColor = get_pixel32 (pSur_Font, k + x, l + y) ;
                    std::cout << "Farbe ist : " << pColor << endl;
    
                    if (pColor == 0xFF000000) {
                        for (s = 0 ; s < size ; s++) {
                            for (d = 0 ; d < size ; d++) {
                                put_pixel32(g_pBackBuffer, (w + xPos + charSpacing) + s, (h + yPos) + d, color);
                            }
                        }
                    }
                    h += size ;
                    l++ ;
                }
                w += size ;
                k++ ;
            }
    
        }   
        //SDL_UnlockSurface(g_pBackBuffer);
    
        SDL_UpdateRect(g_pBackBuffer, 0, 0, 0, 0);   
    }
    
    int main(int argc, char *argv[])
    {
       SDL_Init(SDL_INIT_VIDEO);
       g_pBackBuffer = SDL_CreateRGBSurface(SDL_HWSURFACE,640, 480, 32, RMASK, GMASK, BMASK, AMASK);
       SDL_Surface* screen = SDL_SetVideoMode (640, 480, 32, SDL_HWSURFACE);
       dawString("meintollertest",10,20, 0xFFFF00AA, 1);
       SDL_BlitSurface(g_pBackBuffer,0, screen, 0);
       //SDL_BlitSurface(pSur_Font,0,screen,0);
       SDL_Flip(screen);
       char c;
       cin>>c;
       return 0;
    }
    


  • hmm.

    Ok, ich hab die stellen jetzt so übernommen, ohne erfolg, ich bekomme immer noch den selben "müll" als Farbwerte.

    Dann wollte ich mal direkt deinen Code ausprobieren,

    Hab die stelle des Laden des Bildes geändert, da ich SDL Image nicht habe.

    Also, probierer ich es so, bekomm ich den selben "müll" raus, also ist der einige unterschied ja nur, die art und weiße wie das bild der Font geladen wird.

    #include <iostream>
    #include "SDL.h"
    using namespace std;
    
        #if SDL_BYTEORDER == SDL_BIG_ENDIAN
            const Uint32 RMASK = 0xff000000;
            const Uint32 GMASK = 0x00ff0000;
            const Uint32 BMASK = 0x0000ff00;
            const Uint32 AMASK = 0x000000ff;
        #else
            const Uint32 RMASK = 0x000000ff;
            const Uint32 GMASK = 0x0000ff00;
            const Uint32 BMASK = 0x00ff0000;
            const Uint32 AMASK = 0xff000000;
        #endif
    
    SDL_Surface* g_pBackBuffer;
    SDL_Surface *pSur_Font;
    
    struct Chars
    {
        int        x;
        int        y;
        char    *smallChar;
    };
    
    Uint32 get_pixel32( SDL_Surface *surface, int x, int y )
    {
        //Convert the pixels to 32 bit
        void* target = (surface->pixels);
        char* tmp = reinterpret_cast<char*>(target);
        tmp+=y*(surface->pitch)+4*x;
        return *reinterpret_cast<Uint32*>(tmp);
        //Get the requested pixel
    }
    
    void put_pixel32( SDL_Surface *surface, int x, int y, Uint32 color )
    {
        //Convert the pixels to 32 bit
        void* target = (surface->pixels);
        char* tmp = reinterpret_cast<char*>(target);
        tmp+=y*(surface->pitch)+4*x;
        *reinterpret_cast<Uint32*>(tmp) = color;
    }
    
    void dawString (char *string,int xPos, int yPos, Uint32 color, int size)
    {
        int        j, i;
        int        x, y;
        int        w, h;
        int        k, l;
        int        s, d;
        bool    found = false ;
        int        len = strlen (string) ;
        int        charSize = 10 * size ;
        int        charSpacing ;
        Uint32 pColor;
    
        std::cout << "Zeichne string" << endl;
    
        pSur_Font = SDL_LoadBMP("C:\\Users\\Ich\\Documents\\Visual Studio 2010\\Projects\\SDL test\\SDL test\\Img\\Font.bmp");
        //SDL_Surface *pSur_Font = IMG_Load_RW(SDL_RWFromFile("74zzieba.png", "rb"), 1);
        struct Chars pMyChars[] =
        {
        0,  0, "a",
        10, 0, "b",
        20, 0, "c",
        30, 0, "d",
        40, 0, "e",
        50, 0, "f",
        60, 0, "g",
        70, 0, "h",
        80, 0, "i",
        90, 0, "j",
        100, 0, "k",
        110, 0, "l",
        120, 0, "m",
        0, 10, "n",
        10, 10, "o",
        20, 10, "p",
        30, 10, "q",
        40, 10, "r",
        50, 10, "s",
        60, 10, "t",
        70, 10, "u",
        80, 10, "v",
        90, 10, "w",
        100, 10, "x",
        110, 10, "y",
        120, 10, "z",
        0, 20, " ",
        10, 20, "1",
        20, 20, "2",
        30, 20, "3",
        40, 20, "4",
        50, 20, "5",
        60, 20, "6",
        70, 20, "7",
        80, 20, "8",
        90, 20, "9",
        100, 20, "0",
        };
        int charAnz = (sizeof (pMyChars) / sizeof (pMyChars[0]));
    
        std::cout << "Anzahl aller möglichen zeichen : " << charAnz << endl;
    
        //SDL_LockSurface(g_pBackBuffer);
    
        for (j = 0 ; j < len ; j++) {      
            charSpacing = charSize * j ;
            for (i = 0 ; i < charAnz ; i++) {
                if (pMyChars[i].smallChar[0] == string[j]) {
                    found = true ;
                    x = pMyChars[i].x ;
                    y = pMyChars[i].y ;
                    std::cout << pMyChars[i].smallChar << endl;
                }
            }
            if (!found) {
                continue ;
            }
    
            w = 0 ;
            k = 0 ;
            while (w < charSize) {
                h = 0 ;
                l = 0 ;
                while (h < charSize) {
                    pColor = get_pixel32 (pSur_Font, k + x, l + y) ;
                    std::cout << "Farbe ist : " << pColor << endl;
    
                    if (pColor == 0xFF000000) {
                        for (s = 0 ; s < size ; s++) {
                            for (d = 0 ; d < size ; d++) {
                                put_pixel32(g_pBackBuffer, (w + xPos + charSpacing) + s, (h + yPos) + d, color);
                            }
                        }
                    }
                    h += size ;
                    l++ ;
                }
                w += size ;
                k++ ;
            }
    
        }  
        //SDL_UnlockSurface(g_pBackBuffer);
    
        SDL_UpdateRect(g_pBackBuffer, 0, 0, 0, 0);  
    }
    
    int main(int argc, char *argv[])
    {
       SDL_Init(SDL_INIT_VIDEO);
       g_pBackBuffer = SDL_CreateRGBSurface(SDL_HWSURFACE,640, 480, 32, RMASK, GMASK, BMASK, AMASK);
       SDL_Surface* screen = SDL_SetVideoMode (640, 480, 32, SDL_HWSURFACE);
       dawString("meintollertest",10,20, 0xFFFF00AA, 1);
       SDL_BlitSurface(g_pBackBuffer,0, screen, 0);
       //SDL_BlitSurface(pSur_Font,0,screen,0);
       SDL_Flip(screen);
       char c;
       cin>>c;
       return 0;
    }
    

    Jetzt hab ich mir mal SDL Image runtergeladen und wollte es Compilieren, jedoch

    mit diesen linker errors :

    2>LINK : fatal error LNK1104: Datei "..\Release\SDL_image.lib" kann nicht geöffnet werden.
    1>     Bibliothek ".\Debug\SDL_image.lib" und Objekt ".\Debug\SDL_image.exp" werden erstellt.
    1>IMG_png.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__png_sig_cmp" in Funktion "_IMG_InitPNG".
    1>IMG_png.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__png_set_strip_16" in Funktion "_IMG_InitPNG".
    1>IMG_png.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__png_set_read_fn" in Funktion "_IMG_InitPNG".
    1>IMG_png.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__png_set_packing" in Funktion "_IMG_InitPNG".
    1>IMG_png.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__png_set_gray_to_rgb" in Funktion "_IMG_InitPNG".
    1>IMG_png.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__png_set_expand" in Funktion "_IMG_InitPNG".
    1>IMG_png.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__png_read_update_info" in Funktion "_IMG_InitPNG".
    1>IMG_png.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__png_read_info" in Funktion "_IMG_InitPNG".
    1>IMG_png.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__png_read_image" in Funktion "_IMG_InitPNG".
    1>IMG_png.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__png_get_valid" in Funktion "_IMG_InitPNG".
    1>IMG_png.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__png_get_tRNS" in Funktion "_IMG_InitPNG".
    1>IMG_png.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__png_get_io_ptr" in Funktion "_IMG_InitPNG".
    1>IMG_png.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__png_get_IHDR" in Funktion "_IMG_InitPNG".
    1>IMG_png.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__png_destroy_read_struct" in Funktion "_IMG_InitPNG".
    1>IMG_png.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__png_create_read_struct" in Funktion "_IMG_InitPNG".
    1>IMG_png.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__png_create_info_struct" in Funktion "_IMG_InitPNG".
    1>IMG_tif.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_TIFFSetErrorHandler" in Funktion "_IMG_InitTIF".
    1>IMG_tif.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_TIFFReadRGBAImage" in Funktion "_IMG_InitTIF".
    1>IMG_tif.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_TIFFGetField" in Funktion "_IMG_InitTIF".
    1>IMG_tif.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_TIFFClose" in Funktion "_IMG_InitTIF".
    1>IMG_tif.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_TIFFClientOpen" in Funktion "_IMG_InitTIF".
    1>.\Debug\SDL_image.dll : fatal error LNK1120: 21 nicht aufgelöste externe Verweise.
    

    Als zusätzliches Includeverzeichniss habe ich :

    C:\SDL-1.2.14\include
    

    angegeben, und als zusätzliches Bibliothekverzeichniss :

    C:\SDL-1.2.14\lib
    

    hmm vorallem dashier verstehe ich nicht :

    fatal error LNK1104: Datei "..\Release\SDL_image.lib" kann nicht geöffnet werden.
    

    ich habe im Basiordner "SDL_image-1.2.10" kein Unterverzeichniss "Release"

    Naja, vllt wisst ihr ja weiter, und danke schonmal für die bisherige hilfe



  • Er findet die SDL_image.lib nicht (erster Fehler) und kann damit natürlich auch nicht alle dazugehörigen funktionen richtig linken. Musst eventuell deine dependencies richtig angeben. Wenn der einzige unterschied der laden des bildes ist, dann MUSS es eigentlich so sein das dein bmp keine normale 32 bit sdl surface ergibt. prüf mal die ganzen format flags, bzw schreib sie hier mal rein.



  • Zu deinem lib-verzeichnis - SDL_image hat eine eigene .lib, ich hab sie bei mir z.B. im ordner F:\dev\libs\sdl\SDL_image-1.2.6\lib
    Der SDL ordner selbst sollte die SDL_image.lib eigentlich nicht enthalten, wenn du sie nicht da reingepackt hast.

    Welche IDE verwendest du denn? VS?



  • std::cout << "Zeichne string" << endl;
        SDL_Surface* tmp = IMG_Load("74zzieba.png");
        SDL_SetAlpha(tmp,0,0);
        pSur_Font =  SDL_CreateRGBSurface(SDL_HWSURFACE,tmp->w, tmp->h, 32, RMASK, GMASK, BMASK, AMASK);
        SDL_BlitSurface(tmp,0,pSur_Font,0);
    

    Kannst auch das alternativ mal beim laden einfügen, und testen ob das geht (das sollte im Zweifelsfalle in eine 32-bit surface konvertieren wenn aus der bmp keine entsprechende rauskommt)

    Bitte bedenke auch, das der code denn ich hier gepostet hab wegen den fehlenden SDL_FreeSurface befehlen extreme memory leaks hat.



  • Zu dem SDL Image :

    Ich benutze VS express, und hab mir hier : http://www.libsdl.org/projects/SDL_image/
    SDL Image runtergeladen.
    Entahalten war darin nur ein paar header files und eben weitere zip packete für die etsprechenden Compilier (vermute ich mal) Also hab das zip für VS ausgepackt.
    Dann hatte ich in dem SDL_Image verezeichniss ein unterverzeichniss namens VisualC, darin enthalten sind ein paar dateien für VS.

    So nun zu dem Surface:

    Ich habe pSur_Font->format ausgewerten, der wert ist immer anders.
    pSur_Font->format_version ist 3
    pSur_Font->flags ist 0

    Und wie soll er denn SDL_image.lib überhaupt finden, dies Lib sollte doch eig. erstellt werden, oder etwa nicht 😕



  • http://www.libsdl.org/projects/SDL_image/release/SDL_image-devel-1.2.10-VC.zip

    Das ist die datei, die du runterladen musst, enthält header und .lib datei.

    (quelle http://www.libsdl.org/projects/SDL_image/)

    Das interessante bei SDL_Surface->format sind eigentlich BitsPerPixel und BytesPerPixel, sowie die verwendeten masks (rmask, gmask, bmask, amask)

    BitsPerPixel sollte 32, bytes per pixel 4 sein - wenn nicht, hast du da dein problem (wenn auch noch nicht die Lösung)



  • Hey.
    Ich danke dir für deine Mühe.

    Das Problem war, ich hatte das Bild einemal mit 16 und einmal mit 24 byte abgespeichert.

    Demnach hatte die Surface auch nur 16 bzw. 24 byte, weshalb die funk get_pixel bzw. put_pixel nur müll ausgespuckt hat.

    MS Pait gibt mir leider nicht die möglichkeit ein Bild mit 32 byte Farbtiefe abzupeichern.

    Ich habs nun einfach so gemacht, wie du es gepostet hast.

    Auch das laden eines png´s mit IMG_Load funktioniert leider nicht. Der Pointer zeigt ledeider immer auf 0 hmm.

    Naja mal schauen wie cih es mache, ob ich algemein auf 24 bzw. 16 byte Farbtiefe umsteige und mir die funktionien umschreibe oder es so mache wie du es geostet hast, natürlich werde ich dann den speicher auch wieder frei geben ^^

    EDIT:

    Ach ne kleine Frage hab ich noch, wenn ich mittels SDL_SetVideoMode () ne surface erstelle, habe ich ja unter windows ein "normales Fenster", Jedoch läst dich dieses nciht verschieben, hab ich da nen style übersehen, den ich angeben muss? ist das ein Fehler? oder ist das einfach so ?

    mfg Und danke für die Geduld



  • Gut, das es jetzt geht.
    ImageLoad zeigt btw auf 0 wenn das bild entweder kein png ist, oder er aber die datei nicht findet. Normalerweise sollte es letzteres sein, ist der Pfad denn wirklich richtig?

    Das SDL fenster sollte sich eigentlich verschieben lassen, könnte höchstens sein das das ein konflikt mit der konsolenausgabe gibt, die das blockiert. Sobald die vorbei is, sollts wieder gehen.


Anmelden zum Antworten