GetPixel and SetPixel

Hello everyone,

can someone point me to a good and fast routine for getting and setting pixel either in a surface or texture?
Something like GetPixel(surface, x,y, colorRGBA) and SetPixel(surface, x,y,colorRGBA).

I tried many functions and tutorials with few results

Thank you very much
Kind regards

For a texture it depends on its access type. If it’s SDL_TEXTUREACCESS_TARGET you can make the texture the target of a renderer (SDL_SetRenderTarget) then set a pixel using SDL_RenderDrawPoint() and read a pixel using SDL_RenderReadPixels() with a one-pixel-square rectangle. Reading a texture won’t be fast though.

1 Like

Thank you very much.

Is there any example code around?

I have this code that is working and it’s quite fast.
The problem is that i can’t create a getPixel(x,y,color) putPixel(x,y,color) routine out of this.
How to calculate x and y in the pixels and pixelCount?

        //Lock texture
	if( !gFooTexture.lockTexture() ) {
		printf( "Unable to lock Foo' texture!\n" );
	} else {
        //Manual color key
		//Allocate format from window
		Uint32 format = SDL_GetWindowPixelFormat( gWindow );
		SDL_PixelFormat* mappingFormat = SDL_AllocFormat( format );

		//Get pixel data
		Uint32* pixels = (Uint32*)gFooTexture.getPixels();
		int pixelCount = ( gFooTexture.getPitch() / 4 ) * gFooTexture.getHeight();

		//Map colors
		Uint32 colorKey = SDL_MapRGB( mappingFormat, 0, 0x00, 0x00 );
		Uint32 vertexPoint = SDL_MapRGB( mappingFormat, 255, 0, 0);
		Uint32 transparent = SDL_MapRGBA( mappingFormat, 0xFF, 0xFF, 0xFF, 0x00 );


        bool newTransp = false;
		//Color key pixels
		for( int i = 0; i < pixelCount; ++i ) {

			if( pixels[ i ] == colorKey ) {
				pixels[ i ] = transparent;
				newTransp = true;
            } else {
                if (newTransp==true) {
                    pixels[ i-1 ] = vertexPoint;
                    newTransp=false;
                }
	}
}

	//Unlock texture
	gFooTexture.unlockTexture();

	//Free format
	SDL_FreeFormat( mappingFormat );

Please note this comment at the docs for SDL_LockTexture(): “As an optimization, the pixels made available for editing don’t necessarily contain the old texture data. This is a write-only operation”. So if you’re using it to implement GetPixel it’s not guaranteed to work.

I see, thank you.
Btw i need to getpixel(x,y,color) including alpha and then putpixel(x,y,color).
As i said this code works fast and i can read the the pixel and change the color with this line: pixels[ i-1 ] = vertexPoint;
I need to do this in a loop but having the x,y coordinates of the pixel

Like you said, you can change any pixel using pixels[i] where the index i is in the range [0, width * height).
This works because the pixels array is essentially a 1-dimensional array with all the pixels sequentially from left to right, top to bottom.

If you want to be able to use x and y instead of i, you simply to need to use x and y together to calculate the corresponding i index.

Generally, this is: i = y * width + x
Or more specifically in this case, pixels[i] could be replaced with:
pixels[y * (gFooTexture.getPitch() / 4) + x]

Let me know if I misunderstood your question.

Thank you very much Danny-E33.
The formula seems works quite well. I can get the setPixel function out of it. Don’t know if the speed will be good enough, but i will do some test.

Edit: i can set the pixel using the formula, but how do i get the pixel? I mean the pixel at x,y position and the color information (RGBA)?

Here how i managed to get the pixel values:

Uint8 r, g, b, a;
            for (x=0; x<= gFooTexture.getWidth(); x++) {
                SDL_GetRGBA(pixels[y * (gFooTexture.getPitch() / 4) + x], mappingFormat, &b, &g, &r, &a);
                printf("i = %u, r = %u, g = %u, b = %u, a = %u\n", pixels[y * (gFooTexture.getPitch() / 4) + x], r, g, b, a);
			}

Have to test for the correctness of the code, tho.

@rtrussell @Danny-E33
The code for putpixel works, while the other for getpixel seems not to correct.

I can try with SDL_GFX that offers function for pixelColor() to get a pixel and pixelRGBA to put a pixel on screen. Can’t find a pixecColorexample, tho.