Bilddaten übertragen



  • Ich habe eine PNG-Bitmap mit SDL_image geladen und möchte nun die Pixeldaten in einen anderen Speicherbereich zur Bearbeitung übertragen. Das soll Byte für Byte geschehen, weil ich später dabei noch Farbänderungen vornehmen möchte. Aber irgendwie reicht mein C-Verständnis noch nicht, um die Daten zu übertragen:

    SDL_Surface* sdlImage;
    	int bpp, height, width, pitch;
    	unsigned char *data;
    	int x, y;
    
    	sdlImage = IMG_Load (filename);
    
    	width = sdlImage->w;
    	height = sdlImage->h;
    	bpp = sdlImage->format->BytesPerPixel;
    	pitch = sdlImage->pitch;
    
    	data = (unsigned char *) malloc (pitch * height * sizeof (unsigned char));
    	for (y = 0; y < height; y++) {
    		for (x = 0; x < pitch; x++) {
    			*data[y * pitch + x] = sdlImage->pixels[y * pitch + x];	// ?? 
    		}
    	}
    

    Die betroffene Zeile liefert die Fehlermeldung:

    error: invalid type argument of `unary *'
    


  • erin schrieb:

    unsigned char *data;
    // ...
    *data[y * pitch + x] = // ...
    

    Da versuchst du, "data" doppelt zu dereferenzieren. Mach es entweder so:

    data[y * pitch + x] = // ...
    

    oder so:

    *(data + y * pitch + x) = // ...
    

    Wobei ich die erste Lösung bevorzugen würde.



  • Stimmt, mir fällt wieder ein, dass eine Array-Variable immer ein Zeiger ist. Die Zuweisung von einem konstanten Wert funktioniert schon mal. Aber der rechte Teil ist noch nicht in Ordnung. Ich habe nun:

    data[y * pitch + x] = sdlImage->pixels[y * pitch + x];
    

    und erhalte vom Compiler die freundliche Nachricht

    error: void value not ignored as it ought to be
    

    Also muss irgendetwas mit dem Zugriff auf ->pixels nicht stimmen.



  • 1. SDL_Surface::pixels ist vom Typ void*, du musst also erst in einen anderen Zeigertyp casten.
    2. Bevor du mit "pixels" auf die Pixel zugreifst, solltest du die Surface sperren.



  • Jawoll, ich fange an, mich in die C-Zeiger zu verlieben. 🙂
    Jedenfalls klappt es so:

    unsigned char *data, *sdldata;
    
    if (SDL_MUSTLOCK (sdlImage)) {
        if ( SDL_LockSurface (sdlImage) < 0 ) return NULL;
    }
    
    data = (unsigned char *) malloc (pitch * sizeY * sizeof (unsigned char));
    sdldata = sdlImage->pixels;
    
    for (y=0; y<sizeY; y++) {
    	for (x=0; x<pitch; x++) {
    		data[y * pitch + x] = sdldata[y * pitch + x];	
    	}
    }
    

    Aber wenn wir schon dabei sind, habe ich noch zwei Ergänzungsfragen.

    1. Es sollen Grafiken geladen und verarbeitet werden, die sowohl 3 Byte als auch 4 Byte Farbtiefe haben. Ist es sinnvoll, alles auf 4 Byte zu bringen (es gibt da ja so eine SDL-Map-Funktion) und dann nicht mit Bytes, sondern mit Pixeln zu arbeiten? Mit sinnvoll meine ich einfacher und effektiver.

    2. Zwischen den Zeilen meine ich irgendwo gelesen zu haben, dass SDL-Surfaces direkt im Speicher der Grafikkarte angelegt werden. Stimmt das?

    Bis jetzt schon mal vielen Dank für die schnelle Hilfe
    Reinhard



  • Hi,

    Es sollen Grafiken geladen und verarbeitet werden, die sowohl 3 Byte als auch 4 Byte Farbtiefe haben. Ist es sinnvoll, alles auf 4 Byte zu bringen (es gibt da ja so eine SDL-Map-Funktion) und dann nicht mit Bytes, sondern mit Pixeln zu arbeiten? Mit sinnvoll meine ich einfacher und effektiver.

    Das kommt sicherlich auf den Zweck an. Wenn es um besonders effektives Arbeiten geht ist es eher nicht der richtige Weg. Ich habe es aber auch so geloest, da dieser Weg wesentlich bequemer ist, als fuer jeden Zweck einzeln eine Verarbeitung durchzuführen (zumindest bei mir, weil ich die Surface auch fuer OpenGL genutzt habe).

    Zwischen den Zeilen meine ich irgendwo gelesen zu haben, dass SDL-Surfaces direkt im Speicher der Grafikkarte angelegt werden. Stimmt das?

    Du kannst beim Erstellen einer Surface angeben, ob sie in den Grafikkartenspeicher oder den Hauptspeicher gespeichert werden soll. Das geschieht mit den Flags SDL_HWSURFACE bzw. SDL_SWSURFACE (in der Reihenfolge).
    Bin mir aber nicht sicher, ob das wirklich verbindlich ist, sprich gezwungener massen umgesetzt wird (z.B. wenn der Grafikkartenspeicher voll ist).

    Gruss,
    DeSoVoDaMu


Anmelden zum Antworten