The answer from nickf, although quite common, is wrong. (Sorry, Nick.) For starters, those are the luminosity numbers for NTSC RGB, not sRGB, which is what computer images use. The right numbers are 0.21, 0.72, 0.07. Secondly, the weightings must be applied to the un-gamma-corrected RGB values, then the gamma correction re-applied. Gamma for sRGB is approximately, 2.2. Precisely, it is a composite function that approximates exponentiation by 1/2.2. Here it is in C++. (I do not speak php. Sorry, you'll need to translate.)
// sRGB luminance(Y) values
const double rY = 0.212655;
const double gY = 0.715158;
const double bY = 0.072187;
// Inverse of sRGB "gamma" function. (approx 2.2)
double inv_gam_sRGB(int ic) {
double c = ic/255.0;
if ( c <= 0.04045 )
return c/12.92;
else
return pow(((c+0.055)/(1.055)),2.4);
}
// sRGB "gamma" function (approx 2.2)
int gam_sRGB(double v) {
if(v<=0.0031308)
v *= 12.92;
else
v = 1.055*pow(v,1.0/2.4)-0.055;
return int(v*255+.5);
}
// GRAY VALUE
int gray(int r, int g, int b) {
return gam_sRGB(
rY*inv_gam_sRGB(r) +
gY*inv_gam_sRGB(g) +
bY*inv_gam_sRGB(b);
);
}