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\$
4
\$\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.

Not the answer you're looking for? Browse other questions tagged .