We have managed to create grayscale picture using the following snippet of codes in SDL. What we need to do now is how to first convert into YUV or YCrCb for it be able to set the luminance value and thereafter back into RGB?

const unsigned int gray = (component1 + component2 + component3) / 3;

const int gray_rgb = SDL_MapRGB(original->format, gray, gray, gray);

First of all, this sort of thing is easier to do if you convert your pixel values to floating-point [0, 1] rather than integer [0, 255] values:

// convert 8-bit int to [0, 1] float
float r = r_int / 255.0f;
float g = g_int / 255.0f;
float b = b_int / 255.0f;

// ... do your processing on the float rgb values ...

// at the end, convert back to 8-bit int (with clamping and rounding)
r_int = int(min(max(r, 0.0f), 1.0f) * 255.0f + 0.5f);
g_int = int(min(max(g, 0.0f), 1.0f) * 255.0f + 0.5f);
b_int = int(min(max(b, 0.0f), 1.0f) * 255.0f + 0.5f);

You can scale the luminance of the image by simply multiplying the RGB values by some constant. Constants less than one will make it darker, and constants greater than one will make it brighter. There's no need to convert to YUV or YCrCb, or even calculate the luminance, if all you want is to make the image brighter or darker.

(You should also technically convert the RGB values from gamma space to linear using the sRGB transformation before operating on them, and convert back afterward...but I'd forgive you if you didn't want to deal with that complication at this point. :) Also, if you do need to calculate the luminance, it's best to convert to linear and average the RGB using the Rec. 709 luma coefficients rather than just doing (r + g + b) / 3. Then convert back to gamma space before displaying the grayscale value on screen.)

  • \$\begingroup\$ For now I get component1 say using this method int source_color = get_pixel32(original, x, y ); const unsigned int component1 = source_color & 0xff;. So based on your suggestion float r = r_int / 255.0f; just take the compoment1/255.Of right? \$\endgroup\$ – biz14 Sep 10 '13 at 18:19
  • \$\begingroup\$ @biz14 Yes, just divide each component by 255.0f. \$\endgroup\$ – Nathan Reed Sep 10 '13 at 18:20
  • \$\begingroup\$ So then just multiple the value is it ?What value to multiple ? \$\endgroup\$ – biz14 Sep 10 '13 at 18:22
  • \$\begingroup\$ @biz14 Whatever value you want. To increase the luminance you'd choose a value greater than 1. For example 1.1 would increase the luminance by 10%. \$\endgroup\$ – Nathan Reed Sep 10 '13 at 18:25
  • \$\begingroup\$ So then I must multiple with all the 3 R G B and with 1.1 right? What is this line doing r_int = int(min(max(r, 0.0f), 1.0f) * 255.0f + 0.5f);? In here the r is r*1.1 for e.g. right ? \$\endgroup\$ – biz14 Sep 10 '13 at 18:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.