I want to have possibility of load image into window and then read specific pixel, change its colour and finally put the pixel something else. Unfortunately reading pixels does not work:
#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;
}
}
}
}
I don't know why the read colour from the same place where I've put its is 0, 0, 0. The strange thing is that the valid colour is in position below the position I've put its:
readColor = getPixelColor(screen, x, y-1); // it is valid colour
printColor(readColor);
it can be some kind of dirty solution, but sometimes I need to read pixel from position y=0, so in this situation my hack does not works.
My current SFML version is SFML-2.4.2 gcc-4.9.2-tdm-32-bit on Windows 7
I tried to answer the question with an example. I think you can build your solution on this. I load an image into the texture of a sprite and then read specific a pixel and change its colour. What I did not understand, you wrote "finally put the pixel something else". Obviously I could not answer this.
When you execute this function you will see a tiny green pixel at 10, 10. Hope this helps.
#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();
}
}