Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

31.05.2012, 13:56

SDL - Farben umrechnen RGBA zu Uint32

Hallo Forum!

Ich suche mir das gerade schon die Finger blutig...
Gestern habe ich es mit Hilfe aus dem Forum endlich hinbekommen, den Farbwert eines Pixels aus einem SDL-Surface auszulesen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Uint32 farbe = 0xff0000ff //rot in hex-Darstellung

SDL_LockSurface (s);
SDL_PixelFormat *format =  s->format;
Uint32 p = getpixel(s, x, y);
SDL_GetRGBA(p, format, &r, &g, &b, &a);
SDL_UnlockSurface (s);

Uint32 ausgabe = SDL_MapRGBA(format, rc, gc, bc, ac);
//Ausgabe eingelesener Farbwert des Pixels, manuell auf "farbe" rot gesetzt.
cout << "Ausgabe: " << hex << ausgabe << endl;
//Ausgabe des manuell festgeleten Rots, auf dass das Pixel manuell gesetzt worden ist.
cout << "Farbe: " << hex << farbe << endl;

cout << "r: " << (int)rc << " g: " << (int)gc << " b: " << (int)bc << " alpha: " << (int)ac << endl;


Folgende Ausgabe erfolgt:
Ausgabe:

Quellcode

1
2
3
Ausgabe: f800
Farbe: ff0000ff
r: ff g: 0 b: 0 alpha: ff


Eigentlich müsste Ausgabe == Farbe sein, da beide Werte ein rot ergeben sollten. Tun sie aber nicht...
Wohingegen die Ausgabe der einzelnen Kanäle r, g, b und alpha noch in Ordnung sind. Erst nachdem ich Sie durch SDL_MapRGBA geschickt habe, kommt da nur Käse raus.

Wo mache ich den Fehler? Wie bekomme ich wieder einen hex-basierten Farbwert aus den eingelesenen r, g, b und a Kanälen?

Danke für eure Hilfe!

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

2

31.05.2012, 14:05

So vielleicht:

C-/C++-Quelltext

1
Uint32 ausgabe = SDL_MapRGBA(format, r, g, b, a);
@D13_Dreinig

3

31.05.2012, 14:27

Oh...

Macht Sinn... Werde ich gleich mal ausprobieren.

4

31.05.2012, 16:30

Hat leider nicht viel genützt...

Aber vielleicht mache ich da auch noch was Falsch. Mit Pointern stehe ich immer noch ein wenig auf Kriegsfuß...

Die Fkt. die nutze, sagt mir folgendes:

C-/C++-Quelltext

1
SDL_GetRGBA(Uint32 pixel, const SDL_PixelFormat * const fmt, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a);


Für r, g, b und a erwartet GetRGBA einen Pointer. Wenn ich hier jetzt die Adresse meiner Variablen mittels &r, &g, &b und &a an die Fkt. übergebe, dann kann ich mir doch ein Konstrukt wie dieses hier sparen, oder?

C-/C++-Quelltext

1
2
3
4
5
6
7
Uint8 r, g, b, a;
Uint8 *pr = &r;
Uint8 *pg = &g;
Uint8 *pb = &b;
Uint8 *pa = &a;

SDL_GetRGBA(p, format, pr, pg, pb, pa);


Aber trotzdem spuckt mit SDL_MapRGBA nur Schrott aus...

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

5

31.05.2012, 17:14

C-/C++-Quelltext

1
2
Uint8 r, g, b, a;
SDL_GetRGBA(pixel, surface->format, &r, &g, &b, &a);

Und dann sind deine Werte in r, g, b und a drin.
Irgendwas unklar daran? Oder liegt dein Bild vllt. nicht im RGBA Format vor?
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

6

31.05.2012, 17:20

Das GetRGBA funktioniert. Auch die Werte die in r, g, b und a stehen sich Plausibel.

Nur wenn ich dann Versuche mit SDL_MapRGBA aus den vier einzelnen 8Bit Werten für r, g, b und a einen 32-Bit hex-Wert zu generieren, schlägt das Fehl:

Ausgabe:

C-/C++-Quelltext

1
2
3
r: ff g: 0 b: 0 alpha: ff //Ausgabe der einzelnen Werte für jeden Kanal
Ausgabe: f800 //Ergebnis von SDL_MapRGBA
Farbe: ff0000ff //Referentwert für Rot


C-/C++-Quelltext

1
2
3
4
5
6
Uint32 farbe = 0xff0000ff;
Uint32 ausgabe = SDL_MapRGBA(format, rc, gc, bc, ac);
//Ausgabe eingelesener Farbwert des Pixels, manuell auf "farbe" rot gesetzt.
cout << "Ausgabe: " << hex << ausgabe << endl;
//Ausgabe des manuell festgeleten Rots, auf dass das Pixel manuell gesetzt worden ist.
cout << "Farbe: " << hex << farbe << endl;

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

7

31.05.2012, 17:25

Ist dann evtl. der Pixel falsch bzw. hat eine andere Farbe als du erwartest?
Ich habe weder die getpixel Funktion bisher gesehen noch kenne ich dein Bild.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

8

31.05.2012, 17:36

Die Farbe und das Pixel passen. Da ich zum einen schon das ganze Surface mit Rot eingefärbt habe und die Ausgabe der Farbwerte aus r, g, b und a passen. Erst wenn ich die Werte in SDL_MapRGBA reingesteckt habe, kommt Schrott raus.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Uint32 farbe = 0xff0000ff //rot in hex-Darstellung

//Pixel holen, die ganze Fläche ist vorher auf 0xff0000ff gesetzt worden.
SDL_LockSurface (s);
SDL_PixelFormat *format =  s->format;
Uint32 p = getpixel(s, x, y);
SDL_GetRGBA(p, format, &r, &g, &b, &a);
SDL_UnlockSurface (s);

//Ausgabe der ausgelesenen Werte für Kanal r, g, b und a
cout << "r: " << (int)rc << " g: " << (int)gc << " b: " << (int)bc << " alpha: " << (int)ac << endl
//Ausgabe ---> r: 255 g: 0 b: 0 alpha: 255 <--- das Ergebnis ist korrekt

//Die 8Bit-Werte die oben für das Pixel x/y gewonnen wurden, sollen jetzt mit SDL_MapRGBA in einen 32Bit hex umgewandelt werden: 
Uint32 ausgabe = SDL_MapRGBA(format, rc, gc, bc, ac);
cout << "Ausgabe: " << hex << ausgabe << endl;
//Ergbnis ---> Ausgabe: f800 <--- Da hätte jetzt eigentlich ff0000ff rauskommen sollen...

//Einfache Aussgabe des Referenzwertes Uint32 farbe:
cout << "Farbe: " << hex << farbe << endl;
//Ausgabe ---> Farbe: ff0000ff


Die getpixel-Fkt. stammt aus dem offziellen SDL-Wiki :

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Uint32 getpixel(SDL_Surface *surface, int x, int y)
{
    int bpp = surface->format->BytesPerPixel;
    /* Here p is the address to the pixel we want to retrieve */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
        return *p;
        break;

    case 2:
        return *(Uint16 *)p;
        break;

    case 3:
        if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
            return p[0] << 16 | p[1] << 8 | p[2];
        else
            return p[0] | p[1] << 8 | p[2] << 16;
        break;

    case 4:
        return *(Uint32 *)p;
        break;

    default:
        return 0;       /* shouldn't happen, but avoids warnings */
    }
}

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

9

31.05.2012, 17:36

Zitat


C-/C++-Quelltext

1
SDL_MapRGBA(format, rc, gc, bc, ac);

Was ist denn, bzw was steht denn in, rc, gc, bc und ac?
@D13_Dreinig

10

31.05.2012, 17:38

Wenn ich ein rotes Pixel (gesetzt mit 0xff00ff) auslese, bekomme ich für
rc = 255
gc = 0
bc = 0
ac= 255

Also das hat dann mal geklappt, würde ich sagen.

Werbeanzeige