¿Qué es un Archivo ICO?
ICO es el formato de archivo de icono de Windows, utilizado para almacenar pequeñas imágenes que representan aplicaciones, archivos, carpetas y accesos directos en el sistema operativo Windows. Un solo archivo ICO es un contenedor que almacena múltiples variantes de imagen a diferentes tamaños y profundidades de color — Windows selecciona automáticamente el tamaño más apropiado para cada contexto de visualización (barra de tareas, escritorio, miniatura del Explorador, barra de título, etc.).
El formato fue introducido con Windows 1.0 en 1985 y ha evolucionado significativamente: los archivos ICO modernos pueden incrustar imágenes comprimidas en PNG junto a las capas tradicionales codificadas en BMP, y Windows Vista introdujo soporte para iconos de 256×256 píxeles con transparencia alfa.
Los archivos ICO también se utilizan en el desarrollo web como favicons — los pequeños iconos mostrados en las pestañas del navegador, marcadores y barras de direcciones.
Tamaños Estándar de Iconos
| Tamaño | Contexto |
|---|---|
| 16×16 | Barra de título, vista de lista pequeña, barra de tareas |
| 24×24 | Botones pequeños de barra de herramientas |
| 32×32 | Escritorio (DPI bajo), lista del Explorador |
| 48×48 | Escritorio (DPI medio), vista de lista grande |
| 128×128 | Vista de miniaturas de carpeta |
| 256×256 | Escritorio (DPI alto), iconos grandes del Explorador |
Para pantallas HiDPI/Retina, incluir 256×256 asegura una representación nítida en todos los ajustes de DPI.
Crear Archivos ICO
Usando Python con Pillow
pip install Pillow
from PIL import Image
import os, glob
def crear_ico_desde_png(
png_origen: str,
ico_salida: str,
tamanios: list = None,
) -> None:
"""Convierte un PNG a ICO con múltiples tamaños incrustados."""
if tamanios is None:
tamanios = [16, 24, 32, 48, 64, 128, 256]
img = Image.open(png_origen).convert('RGBA')
img.save(
ico_salida,
format='ICO',
sizes=[(s, s) for s in tamanios],
)
print(f"ICO guardado: {ico_salida} ({len(tamanios)} tamaños: {tamanios})")
# Uso básico
crear_ico_desde_png('logo_256.png', 'app.ico')
# Favicon (tamaños mínimos)
crear_ico_desde_png('favicon_origen.png', 'favicon.ico', tamanios=[16, 32, 48])
Conversión en Lote de PNG a ICO
def convertir_png_a_ico_en_lote(dir_entrada: str, dir_salida: str, tamanios=None) -> None:
if tamanios is None:
tamanios = [16, 32, 48, 64, 128, 256]
os.makedirs(dir_salida, exist_ok=True)
for ruta_png in glob.glob(os.path.join(dir_entrada, '*.png')):
nombre = os.path.splitext(os.path.basename(ruta_png))[0]
ruta_ico = os.path.join(dir_salida, f'{nombre}.ico')
img = Image.open(ruta_png).convert('RGBA')
img.save(ruta_ico, format='ICO', sizes=[(s, s) for s in tamanios])
print(f" {nombre}.png → {nombre}.ico")
convertir_png_a_ico_en_lote('./iconos_origen', './iconos_salida')
Extraer Imágenes de un Archivo ICO
from PIL import Image
import os
def extraer_marcos_ico(ruta_ico: str, dir_salida: str) -> None:
"""Extrae todas las variantes de tamaño incrustadas de un ICO como PNG."""
os.makedirs(dir_salida, exist_ok=True)
ico = Image.open(ruta_ico)
tamanios = ico.info.get('sizes', [(ico.width, ico.height)])
print(f"ICO contiene {len(tamanios)} tamaños: {sorted(tamanios)}")
for tam in sorted(tamanios):
try:
ico.size = tam
marco = ico.copy().convert('RGBA')
ruta_salida = os.path.join(dir_salida, f'icono_{tam[0]}x{tam[1]}.png')
marco.save(ruta_salida, 'PNG')
print(f" Extraído: {ruta_salida}")
except Exception as e:
print(f" Omitido {tam}: {e}")
extraer_marcos_ico('aplicacion.ico', './iconos_extraidos')
ICO y Favicons para la Web
La Pila Moderna de Favicons
<!-- favicon.ico (raíz) — sirve para IE, navegadores antiguos y marcadores -->
<link rel="shortcut icon" href="/favicon.ico">
<!-- Favicons PNG para navegadores modernos -->
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<!-- Icono táctil de Apple (acceso directo a pantalla de inicio iOS) -->
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<!-- Manifiesto de aplicación web (Android Chrome) -->
<link rel="manifest" href="/site.webmanifest">
<!-- Favicon SVG para representación escalable (Chrome/Firefox modernos) -->
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
Generar un Paquete Completo de Favicon
from PIL import Image
import os
def generar_paquete_favicon(imagen_origen: str, dir_salida: str) -> None:
"""Genera un paquete completo de favicon desde una sola imagen de origen."""
os.makedirs(dir_salida, exist_ok=True)
src = Image.open(imagen_origen).convert('RGBA')
# favicon.ico multi-tamaño
src.save(
os.path.join(dir_salida, 'favicon.ico'),
format='ICO',
sizes=[(16,16), (32,32), (48,48)],
)
# Tamaños PNG
for tam, nombre in [
(16, 'favicon-16x16.png'),
(32, 'favicon-32x32.png'),
(48, 'favicon-48x48.png'),
(192, 'android-chrome-192x192.png'),
(512, 'android-chrome-512x512.png'),
(180, 'apple-touch-icon.png'),
]:
redimensionado = src.resize((tam, tam), Image.LANCZOS)
redimensionado.save(os.path.join(dir_salida, nombre), 'PNG')
print(f" Generado: {nombre}")
print(f"\nPaquete de favicon listo en: {dir_salida}")
generar_paquete_favicon('logo.png', './favicons')
Mejores Prácticas para ICO
Incluye siempre canal alfa — Los iconos ICO de 32 bits (RGBA) soportan transparencia alfa completa, esencial para iconos sobre cualquier color de fondo.
Usa compresión PNG para tamaños grandes — Los archivos ICO modernos (Vista+) incrustan datos PNG para el tamaño 256×256, reduciendo drásticamente el tamaño del archivo frente a la codificación BMP.
Genera desde arte vectorial — Crea el ICO desde SVG o PNG de alta resolución (512×512+) en lugar de escalar imágenes raster pequeñas.
Prueba con múltiples configuraciones de DPI — Comprueba los iconos al 96 DPI (100%), 120 DPI (125%) y 144 DPI (150%) para asegurar una representación nítida.
Conversiones relacionadas
Conversiones frecuentes del catálogo: