C++ (SFML) GetPixel Fehler bei Bildern, die auf der Y-Achse unten liegen

Bronislaw

Cadet 2nd Year
Registriert
Juli 2014
Beiträge
28
Rätsle schon seit über einem Tag über ein unerklärliches Problem, das sich wie folgt äußert:
Habe 3 kleine Bilder ins Fenster geladen. (vgl. Anhang) Wenn ich jetzt z.B. die Farbe Rot feststellen lassen möchte, geht das nur bei den oberen beiden. Wenn ich jedoch auf das untere klicke, kommt ein Fehler "vector subscript out of range".
Laut debugger ist die Zeile mit dem sf::Color schuld. Bei Einsetzen des auskommentierten "break" ist der Fehler zwar weg, aber es tut sich dann nichts, wenn man sowohl auf das rechte als auch auf das untere Bild klickt.
Habe das auch mit bloß einem einzigen Bild versucht, das ich auf die Y-Position 100 (also die Stelle des unteren) gesetzt habe und da kommt auch der vector subscript.... Fehler. Hab schon alles versucht, wie ne 2. for Schleife oder Farbafrage an der nullten Vektorstelle etc. aber es geht aus unerklärlichen Gründen nicht. Wie lässt sich dieser Fehler beheben?

Code:
#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>

int main()
{
    sf::RenderWindow mMainWindow(sf::VideoMode(1000,500), "Map", sf::Style::Close);
    mMainWindow.setFramerateLimit(60);

    sf::Image ImageName;
    sf::Texture TextureName;
    sf::Sprite SpriteName;

    std::vector<sf::Image> ImageVector;
    std::vector<sf::Texture> TextureVector;
    std::vector<sf::Sprite> SpriteVector;
	
    for(int i=0; i<3; i++)
    {
        ImageVector.push_back(ImageName);
        TextureVector.push_back(TextureName);
        SpriteVector.push_back(SpriteName);
    }

    for(int i=0; i<3; i++)
    {
        ImageVector[i].loadFromFile("test0.png");
        TextureVector[i].loadFromImage(ImageVector[i]);
        SpriteVector[i].setTexture(TextureVector[i]);
    }

    SpriteVector[0].setPosition(0,0);
    SpriteVector[1].setPosition(100,0);
    SpriteVector[2].setPosition(0,100);

    int itpos = 0;

    while (mMainWindow.isOpen())
    {
        sf::Event event;
	sf::Vector2i mousePos;
	bool leftclicked = false;

        while (mMainWindow.pollEvent(event))
        {
        switch (event.type)
        {
        case sf::Event::Closed:
            mMainWindow.close();
            break;
	case sf::Event::MouseButtonPressed:
            if (event.mouseButton.button == sf::Mouse::Left) 
	    {
	        leftclicked = true;
		mousePos = sf::Vector2i(event.mouseButton.x, event.mouseButton.y);
		break;
	    }
        }
    }
    if(leftclicked)
    {		
        for (auto& it=SpriteVector.begin(); it!=SpriteVector.end(); ++it)
	{			
	    if((*it).getGlobalBounds().contains(mousePos.x,mousePos.y))
	    {
	        itpos = it - SpriteVector.begin();
		sf::Color color = ImageVector[itpos].getPixel(mousePos.x, mousePos.y);
		std::cout << static_cast<int>(color.r) << std::endl;					
	    }
//	break;
	}
    }
    mMainWindow.clear();
    for (auto& it=SpriteVector.begin(); it!=SpriteVector.end(); ++it)
    {
        mMainWindow.draw(*it);
    }
    mMainWindow.display();
    }
    return 0;
}
3 images.png
 
Zuletzt bearbeitet:
Code:
sf::Color color = ImageVector[itpos].getPixel(mousePos.x, mousePos.y);
Dein Image hat eine Größe von 100 x 100 Pixeln (also 10.000 Pixel).
Du versuchst dann mit der Mausposition auf den Farbwert an der entsprechenden Position zuzugreifen.
Die Mausposition ist jedoch (bei Klick auf die Mitte des unteren Bildes) bei x = 50 und y = 150.
Das Programm versucht dann auf Pixel 15.050 zuzugreifen, was weit über den vorhandenen 10.000 Pixeln des Bildes liegt.

Für die Lösung musst du von der Mausposition die Position des Sprites (x = 0 und y = 100) abziehen (um so x = 50 und y = 50 zu erhalten).

Übrigens der gleiche Fehler tritt auch beim rechten Bild auf. Nur ist dieser durch die Implementierung der getPixel() Methode verdeckt.
Code:
Color Image::getPixel(unsigned int x, unsigned int y) const
{
    const Uint8* pixel = &m_pixels[(x + y * m_size.x) * 4];
    return Color(pixel[0], pixel[1], pixel[2], pixel[3]);
}
x = 150 und y = 50 ergibt Pixel 5.150, was noch innerhalb der 10.000 Pixel des Bildes ist, aber nicht dem gewünschten Pixel (5.050) entspricht.

Edit: Dein break befindet sich außerhalb des if-Blocks. Daher wird die for-Schleife nur einmal durchlaufen, also nur auf das erste Element zugegriffen. Der break müsste innerhalb des if-Blocks stehen.
 
Zuletzt bearbeitet:

Ähnliche Themen

Zurück
Oben