我的任务是创建一个小应用程序,您可以上传图片,应用程序将把它变成ASCII艺术.我相信这些已经存在,但我想证明我可以自己做.
这将涉及拍摄图像,使其成为灰度,然后根据图片的暗度和字符的完整程度将每个像素与字符匹配.
所以我的问题是,使用GD库(或者我想其他一些必要的手段)如何使图像变成黑白图像?
正如nickf在他的评论中指出的那样,简单的公式(pixel.r + pixel.g + pixel.b) / 3
是不正确的.使用GD-included函数imagefilter()
(不需要使用PHP循环迭代图像中的所有像素):
$im = imagecreatefrompng('dave.png'); imagefilter($im, IMG_FILTER_GRAYSCALE); imagepng($im, 'dave.png');
要使它纯粹是黑色和白色(正如你所写的那样)使用它
imagefilter($im, IMG_FILTER_GRAYSCALE); imagefilter($im, IMG_FILTER_CONTRAST, -1000);
尼克的答案虽然很普遍,但却是错误的。(对不起,尼克。)首先,这些是计算机图像使用的NTSC RGB而不是sRGB的光度数字。正确的数字是0.21、0.72、0.07。其次,必须将权重应用于未经伽玛校正的RGB值,然后重新应用伽玛校正。sRGB的Gamma约为2.2。确切地说,它是一个复合函数,其乘幂近似为1 / 2.2。它在C ++中。(我不会说php。对不起,您需要翻译。)
// 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) ); }