2017-10-15 9 views
0

Je veux avoir la possibilité de charger l'image dans la fenêtre, puis lire un pixel spécifique, changer sa couleur et enfin mettre le pixel autre chose. Malheureusement, la lecture pixels ne fonctionne pas:pixel avec la couleur specyfic n'est pas dans la position où il a été mis en SFML

#include <iostream> 
using namespace std; 

#include <SFML/Graphics.hpp> 
#include <SFML/config.hpp> 

inline bool isOnScreen(const sf::RenderWindow& screen, int x, int y) 
{ 
    return 0 <= x && x < screen.getSize().x && 0 <=y && y < screen.getSize().y; 
} 

void setPixelColor(sf::RenderWindow& screen, int x, int y, const sf::Color& color) 
{ 
    if (isOnScreen(screen, x, y)) 
    { 
     sf::Vertex vertex(sf::Vector2f(x, y), color); 
     screen.draw(&vertex, 1, sf::Points); 
    } 
    else 
    { 
     cerr << "point " << x << ", " << y << " out of screen, which is: " << screen.getSize().x << ", " << screen.getSize().y << "!\n"; 
    } 
} 

sf::Color getPixelColor(sf::RenderWindow& screen, int x, int y) 
{ 
    if (isOnScreen(screen, x, y)) 
    { 
     return screen.capture().getPixel(x, y); 
    } 
    cerr << "Out of stage: " << x << ", " << y << endl; 
    return sf::Color::Transparent; 
} 

void printColor(const sf::Color& color) 
{ 
    cout << "Color: " << (int)color.r << ", " << (int)color.g << ", " << (int)color.b << '\n'; 
} 

int main() 
{ 
    sf::RenderWindow screen(sf::VideoMode(900, 600), "window"); 

    sf::Color myColor{255, 128, 0}; 

    int x=10, y=10; 
    setPixelColor(screen, x, y, myColor); 

    auto readColor = getPixelColor(screen, x, y); // it is 0, 0, 0 
    printColor(readColor); 

    screen.display(); 

    while (screen.isOpen()) 
    { 
     sf::Event event; 
     while (screen.pollEvent(event)) 
     { 
      if (sf::Event::Closed == event.type) 
      { 
        screen.close(); 
        break; 
      } 
     } 
    } 
} 

Je ne sais pas pourquoi la couleur de lecture à partir du même endroit où j'ai mis son est 0, 0, 0. La chose étrange est que la couleur est valide en position en dessous de la position que j'ai mis son:

readColor = getPixelColor(screen, x, y-1); // it is valid colour 
    printColor(readColor); 

il peut être une sorte de solution sale, mais parfois, je dois lire pixel de la position y = 0, donc dans cette situation mon bidouille ne fonctionne.

Ma version actuelle SFML est SFML-2.4.2 gcc-4.9.2-tdm-32 bits sur Windows 7

Répondre

1

J'ai essayé de répondre à la question par un exemple. Je pense que vous pouvez construire votre solution à ce sujet. Je charge une image dans la texture d'un sprite, puis je lis un pixel spécifique et change sa couleur. Ce que je n'ai pas compris, vous avez écrit "enfin mettre le pixel autre chose". Évidemment, je ne pouvais pas répondre à cela. Lorsque vous exécutez cette fonction, vous verrez un petit pixel vert à 10, 10. J'espère que cela vous aidera.

#include <iostream> 
using namespace std; 

#include <SFML/Graphics.hpp> 

sf::Color setPixelColor(sf::Texture& texture, int x, int y, sf::Color color){ 
    // Get texture image 
    sf::Image image = texture.copyToImage(); 

    // Optional show case: read size of image (not used in this function) 
    int width = image.getSize().x; 
    int height = image.getSize().y; 

    // Get color of specific position 
    sf::Color imagecolor = image.getPixel(x, y); 

    // Just an example: if alpha is above 128, make it green 
    if (imagecolor.a > 128){ 
    imagecolor.g = 255; 
    } 

    // Set pixel to color 
    image.setPixel(x, y, color); 

    // Update texture 
    texture.loadFromImage(image); 
} 

int main(){ 
    sf::RenderWindow screen(sf::VideoMode(900, 600), "window"); 

    sf::Sprite background; 
    sf::Texture texture; 

    if (!texture.loadFromFile("background.png")){ 
    cout << "Error loading texture" << endl; 
    } 
    background.setTexture(texture); 

    while (screen.isOpen()){ 
    sf::Event event; 
    while (screen.pollEvent(event)){ 
     if (sf::Event::Closed == event.type){ 
     screen.close(); 
     break; 
     } 
    } 

    setPixelColor(texture, 10, 10, sf::Color::Green); 

    screen.clear(); 
    screen.draw(background); 
    screen.display(); 
    } 
}