1
\$\begingroup\$

In the same vein as this question and this question, I recently ran into a problem in my C++/SDL2 game architecture where I needed to get the R,G,B values from a clicked pixel in an image on the screen. That is, if the user clicked on a given image surface (SDL_Surface) or texture (SDL_Texture), it would give you back the R,G,B values of the specific pixel in the image that you clicked. The specific use case was for a color picker, to allow users to customize UI elements with a clickable color palette.

This resulted in many hours of keyboard-bashing, because it turns out that SDL2 really, really is not built to have simple solutions to such problems when it comes to shaders and graphics architecture (and that's completely fine - it comes with the efficiency of the library).

Therefore, to save future game developers using C++/SDL2 the massive headache I had to endure, I'm posting the method I discovered below as a self-answer to this question. Hopefully it's helpful to someone with a similar problem in the future!

\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

After much scouring the Internet, I discovered this forum post, containing the following code that completely solved my problem. I've abridged it slightly for easy copy-paste into your project.

SDL_Color GetPixelColor(const SDL_Surface* pSurface, const int X, const int Y)
{
  // Bytes per pixel
  const Uint8 Bpp = pSurface->format->BytesPerPixel;

  /*
  Retrieve the address to a specific pixel
  pSurface->pixels  = an array containing the SDL_Surface' pixels
  pSurface->pitch       = the length of a row of pixels (in bytes)
  X and Y               = the offset on where on the image to retrieve the pixel; (0, 0) is the upper left corner
  */
  Uint8* pPixel = (Uint8*)pSurface->pixels + Y * pSurface->pitch + X * Bpp;

  Uint32 PixelData = *(Uint32*)pPixel;

  SDL_Color Color = {0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE};

  // Retrieve the RGB values of the specific pixel
  SDL_GetRGB(PixelData, pSurface->format, &Color.r, &Color.g, &Color.b);

  return Color;
}

All you need to do is provide:

  • the SDL_Surface that was clicked into the function.
  • the X and Y coordinates of the mouse click.

It will return the SDL_Color object of the pixel clicked - which can subsequently be broken up into R,G,B values if needed using the .r (red), .g (green), and .b (blue) properties.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.