Saltar al contenido
100 % local · 0 KB subidosComprimir PDF

Cómo los PDF almacenan texto e imágenes (por dentro)

Un PDF es un archivo de texto con blobs binarios dentro. La estructura es sorprendentemente legible: una cabecera, una lista de objetos numerados, una tabla de referencias cruzadas y un trailer. Esta página recorre esa estructura y muestra dónde viven realmente el texto, las fuentes y las imágenes. Escrito para desarrolladores y cualquiera que quiera entender qué hace una herramienta PDF cuando lee o escribe un archivo.

Visión general

Las cuatro partes de un PDF

Cada archivo PDF tiene el mismo diseño de cuatro partes:

  1. Cabecera — una línea, p. ej. %PDF-1.7, declarando la versión.
  2. Cuerpo — una secuencia de objetos indirectos numerados. Aquí es donde vive todo: páginas, fuentes, imágenes, metadatos.
  3. Tabla de referencias cruzadas (xref) — desplazamientos de bytes de cada objeto, para que un lector pueda encontrarlos sin escanear todo el archivo.
  4. Trailer — apunta al objeto raíz (el catálogo del documento), a la ubicación del xref y a información opcional de cifrado. El lector lee el trailer primero, luego salta a la raíz.

El diseño trailer-primero es por lo que un PDF se puede leer en tiempo constante sin cargar todo el archivo — importante para documentos enormes y lectores por streaming.

Cuerpo

Objetos indirectos

Cada objeto en el cuerpo está numerado y se ve así:

3 0 obj
<< /Type /Page /MediaBox [0 0 612 792] /Contents 4 0 R /Resources << /Font << /F1 5 0 R >> >> >>
endobj

El 3 0 obj dice "este es el objeto 3, generación 0". El cuerpo dentro de << ... >>es un diccionario — una lista de pares clave/valor. Los valores pueden ser números, cadenas, nombres (con prefijo/), arrays, otros diccionarios o referencias como 4 0 R ("ve a mirar el objeto 4"). Así es como una página apunta a su stream de contenido y a sus fuentes sin incrustarlas.

El número de generación suele ser 0. Se incrementa cuando una actualización incremental borra y reescribe un objeto — una característica que permite editar PDFs añadiendo cambios al final del archivo sin reescribir todo. La mayoría de escritores modernos reescriben todo el archivo, así que las generaciones se quedan en 0.

Contenido

Cómo se almacena el texto

El contenido de la página vive en un stream de contenido — un objeto cuyo valor es un stream de bytes (a menudo comprimido con Flate) que contiene operadores de dibujo PDF. El texto se dibuja con operadores como BT (begin text),Tf (set font y size), Td (move position), Tj (show text) y ET(end text). Un simple "Hello" se ve aproximadamente así:

BT
/F1 24 Tf
100 700 Td
(Hello) Tj
ET

La cadena (Hello) usa la codificación de la fuente. Para texto latino simple suele ser WinAnsiEncoding o la codificación integrada de la fuente. Para texto Unicode, la cadena es una cadena de bytes codificada en 16 bits y la fuente tiene un mapeo/ToUnicode que permite a los lectores recuperar los code points reales para copiar-pegar y buscar. Si un PDF tiene copiar-pegar corrupto pero texto visible, el mapeo /ToUnicode falta o es incorrecto — un bug de exportación común.

El texto no se almacena como HTML o párrafos. No hay objeto semántico "párrafo". Las líneas, los saltos de línea y el posicionamiento son todos comandos de dibujo explícitos. Por eso reflowing un PDF a una anchura de página diferente es difícil: el lector tendría que ingeniería inversa el diseño a partir de comandos de dibujo.

Fuentes

Incrustación de fuentes

Un objeto fuente en PDF tiene dos partes: undiccionario de fuente que nombra la fuente y apunta a sus datos, y el programa de fuente mismo (Type 1, TrueType u OpenType) incrustado como stream. La especificación PDF requiere que las fuentes se incrusten para que el documento se renderice idénticamente en todas partes — pero no lo impone, por lo que algunos PDFs sustituyen fuentes en máquinas que no las tienen.

Subsetting incrusta solo los glifos realmente usados en el documento. Una fuente de 250 KB usada para un solo título se convierte en un subset de 8 KB. La mayoría de exportadores modernos hacen subset por defecto. Exportadores antiguos o ciertas rutas "Print to PDF" a veces incrustan la fuente completa, lo que es una causa común de archivos inflados. Consulta nuestraguía de tamaño de archivo para el desglose completo.

Imágenes

Cómo se almacenan las imágenes

Las imágenes se almacenan como XObjects(objetos externos) — streams de datos de píxeles raw o comprimidos con un diccionario que describe anchura, altura, espacio de color, bits por componente y filtro. El stream de contenido de la página luego dibuja la imagen con el operador Do.

PDF soporta varios filtros de imagen (compresión):

  • DCTDecode — JPEG. Con pérdidas, bueno para fotos. La fuente más común de tamaño en PDFs ricos en imágenes.
  • FlateDecode — zlib/deflate. Sin pérdidas, bueno para arte lineal e imágenes con pocos colores.
  • JPXDecode — JPEG2000. Mejor compresión que JPEG a alta calidad, pero más lento y menos universalmente soportado.
  • JBIG2Decode — para texto escaneado bitonal (1-bit). Puede reducir drásticamente páginas escaneadas.
  • CCITTFaxDecode — compresión clásica de fax para imágenes bitonales.

Un PDF rico en imágenes es sobre todo una secuencia de streams de imágenes comprimidas. Recodificar esos streams con una calidad JPEG más agresiva es la palanca única más grande de tamaño para documentos escaneados.

Índice

Tabla xref y trailer

La tabla xref lista el desplazamiento de bytes de cada objeto indirecto. Un lector abre el archivo, lee el trailer (que está en un desplazamiento conocido desde el final del archivo), encuentra el xref y lo usa para saltar directamente a cualquier objeto sin parsear todo el archivo. Esto es lo que hace PDF random-access.

PDF 1.5 añadió streams de referencias cruzadas, que comprimen la tabla xref misma. Combinado con streams de objetos (muchos objetos pequeños empaquetados en un stream comprimido), esta es la compresión estructural que hace los PDFs modernos más pequeños que sus equivalentes 1.4. Consulta nuestroexplainer de compresión para qué hace esto en la práctica.

El trailer también apunta a/Root (el catálogo del documento, que lista el árbol de páginas), al diccionario /Info(Title, Author, CreationDate — los metadatos) y opcionalmente al diccionario /Encrypt si el archivo está cifrado.

Compresión

Streams y filtros

Cualquier objeto cuyo valor son datos binarios (un stream de contenido, una imagen, una fuente incrustada) es unstream: un diccionario seguido destream, bytes raw y endstream. La entrada /Filter del diccionario le dice al lector cómo decodificar los bytes —FlateDecode para zlib, DCTDecodepara JPEG, etc. Múltiples filtros se pueden encadenar, p. ej. una imagen que se decodifica y luego se downsampea.

Por eso "comprimir un PDF" no es una operación. Cada stream se comprime independientemente con su propio filtro. Una herramienta de compresión que re-guardar con streams de objetos reduce el overhead estructural; recodificar imágenes con una calidad JPEG más agresiva reduce los streams de imágenes. Son palancas independientes.

En la práctica

Por qué esto importa para las herramientas PDF

Cuando una herramienta como IXPDF combina, divide o rota un PDF, parsea el xref, recorre el árbol de páginas, copia o reorganiza los objetos de página y reescribe el xref y el trailer. Los streams de contenido (texto e imágenes) se copian byte a byte — sin recodificación, sin pérdida de calidad. Por eso las operaciones estructurales son rápidas y sin pérdidas: reorganizan referencias de objetos, no re-renderizan la página.

La compresión es la excepción: re-serializa la estructura con streams de objetos. Incluso entonces, los streams de imágenes y fuentes se copian tal cual a menos que el usuario pida explícitamente recodificarlos.

Todo esto ocurre en tu navegador vía un Web Worker — el archivo se parsea, modifica y re-serializa localmente. Tu PDF nunca sale de tu dispositivo.

Seguir leyendo

Recursos relacionados