must - php gd install
Hacer una imagen en escala de grises con la Biblioteca GD (6)
Mi misión es crear una pequeña aplicación donde pueda cargar una imagen, y la aplicación la convertirá en arte ASCII. Estoy seguro de que ya existen, pero quiero demostrar que puedo hacerlo yo mismo.
Esto implicaría tomar una imagen, hacerla en escala de grises y luego unir cada píxel con un personaje, dependiendo de cuán oscura sea la imagen y cuán lleno esté el personaje.
Entonces, mi pregunta es: ¿Cómo puedo usar una biblioteca en GD (o supongo que de otro modo si es necesario) cómo puedo hacer una imagen en blanco y negro?
No tiene que convertirlo a escala de grises ... el resultado sería el mismo si calculara qué tan cerca está un píxel de un determinado color (en su caso, una serie de puntos grises), lo cual debería haber hecho de todos modos al comparar su imagen en escala de grises, y luego elegir el personaje apropiado.
Por lo general, en un espacio de color RGB, el valor de 128 para cada componente de color (RG y B) dará un gris medio. También podría poner cualquier valor inferior o superior a 128 para obtener diferentes intensidades (tonos) de gris.
-ANUNCIO
Una fórmula común para convertir RGB a escala de grises es:
Gray scale intensity = 0.30R + 0.59G + 0.11B
Para hacerlo puramente en blanco y negro (como usted escribió) use esto
imagefilter($im, IMG_FILTER_GRAYSCALE);
imagefilter($im, IMG_FILTER_CONTRAST, -1000);
La respuesta de nickf, aunque bastante común, es incorrecta. (Lo siento, Nick.) Para empezar, esos son los números de luminosidad para NTSC RGB, no sRGB, que es lo que usan las imágenes de computadora. Los números correctos son 0.21, 0.72, 0.07. En segundo lugar, las ponderaciones se deben aplicar a los valores RGB no corregidos gamma, luego se vuelve a aplicar la corrección gamma. Gamma para sRGB es aproximadamente, 2.2. Precisamente, es una función compuesta que aproxima la exponenciación en 1 / 2.2. Aquí está en C ++. (No hablo php. Lo siento, tendrás que traducir).
// 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)
);
}
Como señala nickf en su comentario , la fórmula simple (pixel.r + pixel.g + pixel.b) / 3
no es correcta. Utilice el imagefilter()
función incluido imagefilter()
(no es necesario iterar sobre todos los píxeles en una imagen usando bucles PHP) en su lugar:
$im = imagecreatefrompng(''dave.png'');
imagefilter($im, IMG_FILTER_GRAYSCALE);
imagepng($im, ''dave.png'');