Un color son tres números
El color de un píxel se guarda con tres números, uno de rojo, uno de verde y uno de azul, de 0 a 255. Mezclar colores y mezclar con transparencia es una cuenta sencilla con esos tres números.
Es lo que hace tu móvil cuando una ventana semitransparente se pone sobre una foto.
Al final de esta lección
Nota
Puedo mezclar colores y combinar uno con otro usando transparencia.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| RGB | el color como tres números: rojo, verde y azul | (255, 0, 0) |
| Canal | cada uno de los tres números de un color | |
| Alfa | cuánto tapa un color al que tiene detrás | |
| Mezcla | combinar un color de delante con uno de fondo | |
| Saturar | pasar del máximo y quedarse en 255 |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
La pantalla suma luz roja, verde y azul
Cada píxel de una pantalla tiene tres lucecitas: roja, verde y azul. Los tres números de 0 a 255 dicen cuánto brilla cada una. Con 0 está apagada y con 255 brilla al máximo.
Las luces se suman. Rojo más verde da amarillo, y las tres al máximo dan blanco.
Ejemplo resuelto: colores como números
| Color | Rojo | Verde | Azul |
|---|---|---|---|
| Negro | 0 | 0 | 0 |
| Rojo | 255 | 0 | 0 |
| Amarillo | 255 | 255 | 0 |
| Cian | 0 | 255 | 255 |
| Gris medio | 128 | 128 | 128 |
| Blanco | 255 | 255 | 255 |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Suma dos luces y satura
# Suma de luz: el máximo de cada canal es 255.
rojo = (200, 40, 0)
verde = (100, 180, 0)
suma = []
for i in range(3):
suma.append(min(rojo[i] + verde[i], 255))
print(suma)
# Cambia verde a (20, 30, 0) y mira que ya no se llega a 255.
El alfa dice cuánto tapa el color
Con transparencia, el color final es una media entre el de delante y el de fondo. El alfa es el peso del color de delante.
Aquí se da en porcentaje. Con alfa 100 solo se ve el color de delante, con 0 solo el de fondo y con 50 una mezcla a partes iguales. Se calcula canal a canal: (alfa * delante + (100 - alfa) * fondo + 50) // 100.
Ejemplo resuelto: rojo sobre azul con distinto alfa
| Alfa | Rojo | Verde | Azul |
|---|---|---|---|
| 0 | 0 | 0 | 255 |
| 25 | 64 | 0 | 191 |
| 50 | 128 | 0 | 128 |
| 75 | 191 | 0 | 64 |
| 100 | 255 | 0 | 0 |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Mezcla rojo sobre azul al 50 %
docker exec jupyter python3 -c "print(tuple((50 * f + 50 * b + 50) // 100 for f, b in zip((255, 0, 0), (0, 0, 255))))"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Qué imprime la mezcla al 50 por ciento
Imprime (128, 0, 128): un violeta. El rojo sube de 0 a 128 y el azul baja de 255 a 128, justo a la mitad.
El + 50 antes de dividir redondea: 12.750 entre 100 daría 127, pero con el 50 da 128, que es lo más cercano.
Compara con la mezcla de Pillow
docker exec jupyter python3 -c "from PIL import Image; capa = Image.new('RGBA', (1, 1), (255, 0, 0, 128)); fondo = Image.new('RGBA', (1, 1), (0, 0, 255, 255)); print(Image.alpha_composite(fondo, capa).getpixel((0, 0)))"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
En Pillow el alfa llega a 255
Imprime (128, 0, 127, 255): el azul es 127 y no 128. En Pillow el alfa va de 0 a 255, y 128 de 255 es un poco más que la mitad (50,2 por ciento).
La cuarta cifra, 255, es el alfa del resultado: la imagen final es opaca. Con otra escala, la misma fórmula da casi el mismo color.
Un error muy común
Advertencia
Mucha gente cree que mezclar rojo y verde da marrón, como con pinturas. Una pantalla emite luz y las luces se suman: rojo y verde dan amarillo. La pintura es otra cosa, porque absorbe luz en lugar de emitirla.
Guarda una mezcla como imagen
docker exec jupyter python3 -c "from PIL import Image, ImageDraw; fondo = Image.new('RGB', (120, 60), (0, 0, 255)); capa = Image.new('RGBA', (120, 60), (0, 0, 0, 0)); ImageDraw.Draw(capa).rectangle([30, 10, 89, 49], fill=(255, 0, 0, 128)); fondo.paste(capa, (0, 0), capa); fondo.save('mezcla.png'); print(fondo.getpixel((5, 5)), fondo.getpixel((60, 30)), fondo.getpixel((100, 55)))"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Para ir más lejos: abre la mezcla
El último comando guarda mezcla.png, de 120 por 60 píxeles. Ábrela en JupyterLab desde la carpeta de trabajo.
Verás un fondo azul con un rectángulo violeta en el centro: el rojo semitransparente sobre el azul. Cambia el 128 de fill y mira cómo cambia el violeta.