首先,SFML是一个多媒体库,并不是真正的图像库。您当然可以按照您的方式做事,但它并没有真正为此优化,并且涉及相当多的开销。
但是,如果您确实只想进行逐像素转换,我建议您使用 SFML 在 GPU 上渲染目标图像。这样做相当简单:
sf::Texture source;
sf::Sprite sprite;
sf::Shader shader;
// I'll be skipping error checking for simplicity
// Load the shaders (see below)
shader.loadFromFile("shader.fs", sf::Shader::Fragment);
// Tell the shader to use the current texture (i.e. the one bound to the srite)
// This name has to match the one in the shader code; you can bind multiple textures, e.g. for blending
shader.setUniform("texture", sf::Shader::CurrentTexture);
// Load the image
sourceImage.loadFromFile("pic.bmp");
// Assign the texture
sprite.setTexture(sourceImage, true);
// Draw the sprite using the shader
// 'target' can be a 'sf::RenderWindow' or 'sf::RenderTexture'
target.clear();
target.draw(sprite, shader);
target.display();
您将需要一个额外的文件,其中包含您的实际像素操作。
作为替代方案,您可以将其放入字符串文字中,但这样更容易修改。
着色器文件系统
uniform sampler2D texture;
in vec2 tex_coord;
void main()
{
// Get this pixel's color
vec4 pixel = gl_TexCoord[0].xy;
// Let's set 'red' to full (i.e. 255/1.0)
pixel.r = 1.0;
// Return the pixel color
gl_FragColor = pixel;
}
作为替代方案,您当然也可以交换绿色和蓝色通道:
float t = pixel.g;
pixel.g = pixel.b;
pixel.b = t;
还有几乎所有您能想到的其他东西。请注意,此代码未经测试,但应该可以工作(可能存在一两个小问题)。您还可以检查 SFMLShader示例以获取更多信息。
如果您使用的是sf::RenderTexture
作为您的目标,您可以将文件保存到新图像,而不必强制将其绘制在屏幕上。