Making an Image Greyscale with GD Library

感情迁移 提交于 2019-12-01 06:11:26

A common formula to convert RGB to greyscale is:

Gray scale intensity = 0.30R + 0.59G + 0.11B
Stefan Gehrig

As pointed out by nickf in his comment, the simple formula (pixel.r + pixel.g + pixel.b) / 3 is not correct. Use the GD-included function imagefilter() (no need to iterate over all pixels in an image using PHP loops) instead:

$im = imagecreatefrompng('dave.png');
imagefilter($im, IMG_FILTER_GRAYSCALE);
imagepng($im, 'dave.png');

To make it purely black and white (as you wrote) use this

imagefilter($im, IMG_FILTER_GRAYSCALE);
imagefilter($im, IMG_FILTER_CONTRAST, -1000);

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)
    );
}

You don't have to convert it to grayscale... the result would be the same if you just calculated how close a pixel is to a certain colour (in your case a series of gray points), which you would have to have done anyway when comparing your grayscale image, and then chosing the appropriate character.

Typically in a RGB color space, value of 128 for each color component(RG and B) will give a medium gray. You might as well put any value lower or greater than 128 to get different intensities(shades) of gray.

-AD

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!