Reputation: 44648
My mission is to create a little app where you can upload a picture, and the app will turn it into ASCII art. I'm sure these exist already but I want to prove that I can do it myself.
This would involve taking an image, making it greyscale and then matching each pixel with a character depending on how dark the picture is and how full the character is.
So my question is, Using the GD Library (or i guess some other means if necessary) how do I make an image black and white?
Upvotes: 4
Views: 9782
Reputation: 17026
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)
);
}
Upvotes: 5
Reputation: 7887
To make it purely black and white (as you wrote) use this
imagefilter($im, IMG_FILTER_GRAYSCALE);
imagefilter($im, IMG_FILTER_CONTRAST, -1000);
Upvotes: 7
Reputation: 83622
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');
Upvotes: 23
Reputation: 545995
A common formula to convert RGB to greyscale is:
Gray scale intensity = 0.30R + 0.59G + 0.11B
Upvotes: 3
Reputation: 18956
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
Upvotes: 0
Reputation: 119
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.
Upvotes: 1