Cómo convertir GIF a video ASCII en Google Colab
Procesar un archivo GIF mediante código Python en Google Colab para generar un video en formato ASCII art y descargarlo. Guía paso a paso (13 pasos) par…
JUDIS te señala cada botón sobre tu propia pantalla mientras lo haces. Sin la app, los pasos se leen igual aquí.
Antes de empezar
Tener una cuenta de Google con acceso a Google Colab (colab.research.google.com) y el archivo GIF que quieras convertir guardado en tu computadora.
Ten a la mano
- Un archivo GIF que quieras convertir a video ASCII · suele estar en Descargas
Paso a paso
Paso 1
Abre una pestaña nueva del navegador y entra a colab.research.google.com.
Escribe: colab.research.google.com
Listo cuando: Se abre la página de Google Colab con la lista de notebooks.
Paso 2
Abre un notebook de la lista, o crea uno nuevo.
Listo cuando: Se abre el notebook con la barra de menú (Archivo, Editar, Ver, Insertar) y una celda de código.
Paso 3
Haz clic dentro de la celda de código vacía.
Listo cuando: El campo quedó activo (cursor visible) y listo para escribir o pegar contenido.
Paso 4
Antes: El campo de entrada de código debe estar activo (cursor visible) — si no, el código no se pega en el lugar correcto.
Pega el código Python completo en la celda.
# ==========================================
# 1. INSTALACIÓN DE DEPENDENCIAS
# ==========================================
import os
import cv2
import numpy as np
from PIL import Image, ImageEnhance, ImageFilter, ImageDraw, ImageFont
from google.colab import files
# Instalar fuente monoespaciada
!apt-get install -y ttf-dejavu > /dev/null 2>&1
ASCII_CHARS = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvrjfI1?i+~i!lI;:,\"^`'. "
# ==========================================
# 2. PROCESAMIENTO ASCII CON MAYOR ALTURA
# ==========================================
def frame_to_ascii_grid(frame_pil, width_chars=320, height_factor=0.9, contrast=2.4):
img = frame_pil.convert("L")
img = img.filter(ImageFilter.UnsharpMask(radius=2.0, percent=300, threshold=1))
img = ImageEnhance.Contrast(img).enhance(contrast)
w_orig, h_orig = img.size
aspect_ratio = h_orig / w_orig
pixel_width = width_chars
# height_factor a 0.9 aumenta las filas de texto verticalmente
pixel_height = int(pixel_width * aspect_ratio * height_factor)
img_resized = img.resize((pixel_width, pixel_height), Image.Resampling.LANCZOS)
ascii_grid = []
num_chars = len(ASCII_CHARS)
for y in range(pixel_height):
row = []
for x in range(pixel_width):
px = img_resized.getpixel((x, y))
char_idx = int((px / 255) * (num_chars - 1))
row.append(ASCII_CHARS[char_idx])
ascii_grid.append(row)
return ascii_grid, pixel_width, pixel_height
def render_ascii_ultra_tight(
ascii_grid,
pixel_width,
pixel_height,
font_size=12,
bg_color=(0, 0, 0),
text_color=(255, 255, 255)
):
font_path = "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf"
try:
font = ImageFont.truetype(font_path, font_size)
except Exception:
font = ImageFont.load_default()
bbox = font.getbbox("W")
char_w = bbox[2] - bbox[0]
char_h = bbox[3] - bbox[1]
# Paso apretado sin espacios
step_x = char_w * 0.72
step_y = char_h * 0.85
margin = 20
canvas_w = int(pixel_width * step_x) + (margin * 2)
canvas_h = int(pixel_height * step_y) + (margin * 2)
canvas = Image.new("RGB", (canvas_w, canvas_h), color=bg_color)
draw = ImageDraw.Draw(canvas)
for y in range(pixel_height):
for x in range(pixel_width):
char = ascii_grid[y][x]
if char != ' ':
pos_x = margin + (x * step_x)
pos_y = margin + (y * step_y)
draw.text((pos_x, pos_y), char, font=font, fill=text_color)
return canvas
def process_gif_in_colab(gif_path, output_mp4="caballo_ascii_ultra_hd.mp4", width_chars=320):
try:
gif = Image.open(gif_path)
except Exception as e:
print(f"❌ Error al abrir el GIF: {e}")
return None
fps = 12
if "duration" in gif.info and gif.info["duration"] > 0:
fps = 1000 / gif.info["duration"]
frames_processed = []
frame_idx = 0
print(f"🚀 Procesando fotogramas a Alta Resolución ({width_chars} cols)...")
try:
while True:
gif.seek(frame_idx)
frame_pil = Image.new("RGBA", gif.size)
frame_pil.paste(gif)
# 1. Matriz con height_factor=0.9 para dar más altura
ascii_grid, p_w, p_h = frame_to_ascii_grid(
frame_pil,
width_chars=width_chars,
height_factor=0.9,
contrast=2.4
)
# 2. Renderizado compacto
frame_rendered = render_ascii_ultra_tight(
ascii_grid, p_w, p_h,
font_size=12
)
frames_processed.append(frame_rendered)
frame_idx += 1
print(f"✔ Frame {frame_idx} procesado.")
except EOFError:
pass
if not frames_processed:
print("❌ No se encontraron fotogramas.")
return None
# 3. Exportar MP4
v_w, v_h = frames_processed[0].size
if v_w % 2 != 0: v_w += 1
if v_h % 2 != 0: v_h += 1
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_mp4, fourcc, fps, (v_w, v_h))
for frame in frames_processed:
if frame.size != (v_w, v_h):
frame = frame.resize((v_w, v_h))
cv_img = cv2.cvtColor(np.array(frame), cv2.COLOR_RGB2BGR)
out.write(cv_img)
out.release()
print(f"\n🎉 ¡Proceso finalizado! Archivo guardado en Colab como '{output_mp4}'.")
return output_mp4
# ==========================================
# 3. EJECUCIÓN
# ==========================================
print("📂 Sube tu archivo GIF:")
uploaded = files.upload()
if uploaded:
input_gif = list(uploaded.keys())[0]
output_mp4 = "caballo_ascii_ultra_hd.mp4"
res = process_gif_in_colab(input_gif, output_mp4, width_chars=320)
if res and os.path.exists(res):
print("\n📁 El video está listo. Puedes encontrarlo en la pestaña de archivos (ícono de carpeta a la izquierda en Colab) para descargarlo cuando quieras.")Listo cuando: El código aparece en la celda con colores. Empieza con '1. INSTALACIÓN DE DEPENDENCIAS'.
Paso 5
Toca 'Ejecutar todo' para correr el código.
Listo cuando: Abajo aparece 'Asignando entorno de ejecución' y la celda empieza a correr.
Paso 6
Baja hasta el final de la celda, hasta donde dice 'Sube tu archivo GIF'.
Listo cuando: Ves el botón 'Seleccionar archivos'.
Paso 7
Toca 'Seleccionar archivos'.
Listo cuando: Se abre la ventana 'Elige los archivos a cargar'.
Paso 8
Busca tu GIF (suele estar en Descargas) y selecciónalo.
Listo cuando: El archivo queda resaltado en azul.
Paso 9
Antes: Tu GIF debe estar seleccionado (en azul).
Toca el botón 'Cargar'.
Listo cuando: La ventana se cierra y bajo la celda aparece el nombre de tu GIF como subido.
Paso 10
Espera a que el código procese el GIF. No hace falta volver a ejecutar: empieza solo al subirlo.
Listo cuando: Aparecen líneas 'Frame X procesado' y al final un mensaje de que el video se guardó.
Paso 11
Mira el panel de archivos a la izquierda.
Listo cuando: Aparece un archivo .mp4 que termina en '_ascii_ultra_hd.mp4'.
Paso 12
Pasa el mouse sobre el video .mp4 del panel de archivos.
Listo cuando: Junto al archivo aparecen los tres puntos de opciones.
Paso 13
Haz doble clic en el nombre del video para descargarlo. También puedes tocar los tres puntos y elegir 'Descargar'.
Listo cuando: El video se guarda en tu carpeta de Descargas.
Qué puede cambiar en tu caso
El nombre del notebook puede variar (Untitled1, Untitled2, etc.). El nombre de tu GIF y del video resultante dependen del archivo que subas. El tiempo de procesamiento depende de lo largo que sea el GIF.
En qué se suele equivocar la gente
Pegar el código sin haber hecho clic antes dentro de la celda. Tocar 'Cargar' sin haber seleccionado el GIF. Buscar el botón para subir el archivo sin bajar hasta el final de la celda.