Farbe eines Pixels auslesen

Hallo,
ich such jetzt schon seit 5 Tagen nach der Lösung, aber ich bekomm es einfach nicht hin.

Ich benutze SDL2 und C++. Und ich will die Farbe eines bestimmten Pixels, z.B: an der Position x=300, y=250 auslesen in RGB Format.

Ich hab im Internet zwar viele Lösungen gefunden, aber bei allen stürzt mein Programm ab, vielleicht findet jemand den Fehler, oder kann mir sogar einen kleinen Code geben, der funktioniert (natürlich nicht zum sturren abschreiben, sondern dass ich versteh wie es richtig geht)
Naja... hier erstmal mein Code:

Code:
#include "Game.h"
#include "windows.h"


#include <SDL2\SDL.h>
#include <iostream>

// name: AmericaGame / Game.cpp
// author: Lukas Mrosek
// version: 1.0
// date: 09.02.2017
// developed for Augustinus-Gymnasium-Weiden

using namespace std;

#pragma once
bool Game::start() {
    // variables
    high = GetSystemMetrics(SM_CXSCREEN);
    width = GetSystemMetrics(SM_CYSCREEN);

    // init SDL with grafical driver
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0)                                                    {

        std::cerr << "SDL ERROR! MSG:" << SDL_GetError() << std::endl;
        exit(-1);
    }


    // create window
    window = SDL_CreateWindow("AmericaGame", 0, 0, high, width, SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN);
    if (window == NULL){
        std::cerr << "SDL WINDOW ERROR! MSG:" << SDL_GetError() << std::endl;
        exit(-1);
    }


    // create renderer
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);          
    if (renderer == NULL)
    {
        std::cerr << "SDL RENDERER ERROR! MSG:" << SDL_GetError() << std::endl;
        exit(-1);
    }

    background = new Texture(renderer, "bg.bmp");
    background->Draw(0, 0, high, width);


    team1 = new Team("Republikaner");
    team2 = new Team("Demokraten");

    // init states
    initStates();

    SDL_RenderPresent(renderer);
}

void Game::run() {
    running = true;
    while (running) {

        SDL_Event event;
        while (SDL_PollEvent(&event)){
            switch (event.type){
            case SDL_QUIT:
                running = false;
                break;
            case SDL_KEYDOWN:
                switch (event.key.keysym.sym) {
                case SDLK_ESCAPE:
                    running = false;
                    break;
                }
                break;
            case SDL_MOUSEBUTTONDOWN:
                switch (event.button.button) {
                case SDL_BUTTON_LEFT:
                    int xm, ym;
                    SDL_GetMouseState(&xm, &ym);

                   ///////////////////////////////////////////////////////////////////////////////////////////
                   ///////////////////////////////////////////////////////////////////////////////////////////
                   //Dies ist die Auffällige Codemakierung, damit ihr wisst, welche Zeile ich meine //
                   ///////////////////////////////////////////////////////////////////////////////////////////
                   ///////////////////////////////////////////////////////////////////////////////////////////

                  
                   SDL_Surface* img = SDL_GetWindowSurface(window);
                  SDL_PixelFormat* fmt = img->format;
                  SDL_LockSurface(img);
                  Uint32 pixels;
                  Uint8 r, g, b;
                  pixels = getpixel32(img, xm, ym);
                  SDL_GetRGB(pixels, fmt, &r, &g, &b);
                  SDL_UnlockSurface(img);
                 std::cout << "\n\n Rot: " << (int)r << endl;*/
                }
            }
        }
    }

    // shutdown SDL
    SDL_Quit();
}
Uint32 Game::getpixel32(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 */
    }
}

So, bei der "auffälligen Codemakierung" geht die Stelle los, wo ich die Pixelfarbe auslesen will,
Seltsamerweise wird für Rot immer 0 ausgegeben, und ich hab keine Ahnung, wieso, selbst wenn ich auf reines Rot klicke....

Hoffentlich kann mir jmd helfen! Ich brauch das für die Schule ganz dringen und ich bin echt am verzweifeln :/
 
Zuletzt bearbeitet:

Thallius

Top Contributor
Ich würde jetzt mal grob raten, dass getPixel Dir einen RGBA Wert zurück liefert und keinen RGB. Das Ganze dann wahrscheinlich noch in LittleIndian. Das sieht man aber natürlich nur, wenn man sich den Pixelwert mal als hexwert ausgeben läßt

Gruß

Claus
 
Ich würde jetzt mal grob raten, dass getPixel Dir einen RGBA Wert zurück liefert und keinen RGB. Das Ganze dann wahrscheinlich noch in LittleIndian. Das sieht man aber natürlich nur, wenn man sich den Pixelwert mal als hexwert ausgeben läßt

Gruß

Claus
Get_RGB liefert einen RGB Wert, get_RGBA einen RGBA wert ;)
Das mt dem Hexwert klingt vernünftig, sry dass ich jetzt so blöd frag, aber wie geht das :D
 

Thallius

Top Contributor
Get_RGB liefert einen RGB Wert, get_RGBA einen RGBA wert ;)

ein RGB Wert hat aber nunmal nur 24bit und keine 32. Also muss auch bei Get_RGB irgendwas in den restlichen 8 bit stehen. Wenn das dann Nullen sind, würde das z.B. bei LittleEndian erklären warum dein Rot immer 0 ist, denn bei RGB0 steht der 0 wert bei LittleEndian in den ersten 8 Bits.

Das mt dem Hexwert klingt vernünftig, sry dass ich jetzt so blöd frag, aber wie geht das :D

printf("%08lx", wert)
 
Der steht doch in meiner Frage ^^

Code:
#include "Game.h"
#include "windows.h"


#include <SDL2\SDL.h>
#include <iostream>

// name: AmericaGame / Game.cpp
// author: Lukas Mrosek
// version: 1.0
// date: 09.02.2017
// developed for Augustinus-Gymnasium-Weiden

using namespace std;

#pragma once
bool Game::start() {
    // variables
    high = GetSystemMetrics(SM_CXSCREEN);
    width = GetSystemMetrics(SM_CYSCREEN);

    // init SDL with grafical driver
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0)                                                    {

        std::cerr << "SDL ERROR! MSG:" << SDL_GetError() << std::endl;
        exit(-1);
    }


    // create window
    window = SDL_CreateWindow("AmericaGame", 0, 0, high, width, SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN);
    if (window == NULL){
        std::cerr << "SDL WINDOW ERROR! MSG:" << SDL_GetError() << std::endl;
        exit(-1);
    }


    // create renderer
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);        
    if (renderer == NULL)
    {
        std::cerr << "SDL RENDERER ERROR! MSG:" << SDL_GetError() << std::endl;
        exit(-1);
    }

    background = new Texture(renderer, "bg.bmp");
    background->Draw(0, 0, high, width);


    team1 = new Team("Republikaner");
    team2 = new Team("Demokraten");

    // init states
    initStates();

    SDL_RenderPresent(renderer);
}

void Game::run() {
    running = true;
    while (running) {

        SDL_Event event;
        while (SDL_PollEvent(&event)){
            switch (event.type){
            case SDL_QUIT:
                running = false;
                break;
            case SDL_KEYDOWN:
                switch (event.key.keysym.sym) {
                case SDLK_ESCAPE:
                    running = false;
                    break;
                }
                break;
            case SDL_MOUSEBUTTONDOWN:
                switch (event.button.button) {
                case SDL_BUTTON_LEFT:
                    int xm, ym;
                    SDL_GetMouseState(&xm, &ym);

                   ///////////////////////////////////////////////////////////////////////////////////////////
                   ///////////////////////////////////////////////////////////////////////////////////////////
                   //Dies ist die Auffällige Codemakierung, damit ihr wisst, welche Zeile ich meine //
                   ///////////////////////////////////////////////////////////////////////////////////////////
                   ///////////////////////////////////////////////////////////////////////////////////////////

                
                   SDL_Surface* img = SDL_GetWindowSurface(window);
                  SDL_PixelFormat* fmt = img->format;
                  SDL_LockSurface(img);
                  Uint32 pixels;
                  Uint8 r, g, b;
                  pixels = getpixel32(img, xm, ym);
                  SDL_GetRGB(pixels, fmt, &r, &g, &b);
                  SDL_UnlockSurface(img);
                 std::cout << "\n\n Rot: " << (int)r << endl;*/
                }
            }
        }
    }

    // shutdown SDL
    SDL_Quit();
}
Uint32 Game::getpixel32(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 */
    }
}
 
Zuletzt bearbeitet von einem Moderator:

Neue Themen


Oben