PDF Library for Delphi acepta imágenes AVIF, HEIF y JPEG XL como entrada mediante AddModernImageFromFile y sus variantes de flujo y cadena, conservando el alfa, el perfil ICC incrustado y los canales de 16 bits en el trayecto hacia el objeto de imagen PDF. La detección de formato se realiza mediante una lectura acotada de número mágico, y la decodificación pasa por un backend reemplazable, así que no se invoca nada externo para un archivo que en realidad no es ninguno de esos formatos
Estos formatos llegaron a los flujos de trabajo de documentos a través de los teléfonos. iOS produce HEIC por defecto desde hace años, los dispositivos Android producen AVIF, y un técnico de campo que fotografía una pieza dañada envía una imagen que un generador de informes PDF construido en 2015 no puede abrir en absoluto. La vía de respaldo genérica, decodificar mediante un mapa de bits de la plataforma, produce de forma fiable color de 8 bits y pierde el alfa y el perfil de color por el camino
¿Qué conserva la vía de imagen moderna que una conversión a mapa de bits pierde?
Tres cosas, y cada una tiene un flujo de trabajo que depende de ella. El alfa sobrevive, algo que importa para logotipos y recortes de producto compuestos sobre el contenido de página. El perfil ICC sobrevive, algo que importa para todo lo que vaya a imprimirse o a ajustarse de color. Y los canales de 16 bits sobreviven, algo que importa para imágenes médicas y científicas donde la cuantización de 8 bits destruye precisamente las gradaciones para las que se capturó la imagen
Pasar una imagen por un mapa de bits de la plataforma pierde las tres cosas en un solo paso, y lo hace en silencio: el PDF resultante tiene un aspecto aproximadamente correcto, y nadie se da cuenta hasta que una imprenta pregunta por qué el rojo corporativo está mal. El valor de opción 8 en las llamadas de imagen moderna es el indicador que mantiene juntos el alfa, el ICC y los canales de 16 bits, y es el predeterminado para esas llamadas
Añadir una a una página
La llamada devuelve un identificador de imagen, que después se selecciona y se dibuja, o se dibuja y se libera en un solo paso:
uses
PDFlibrary, PDFlibModernImage;
var
Lib: TPDFlib;
ImageID: Integer;
begin
Lib := TPDFlib.Create;
try
Lib.NewDocument;
Lib.SetPageSize('A4');
Lib.NewPage;
// Options = 8 conserva el alfa, el ICC y los canales de 16 bits
ImageID := Lib.AddModernImageFromFile('site-photo.heic', 8);
if ImageID > 0 then
Lib.DrawImageAndRelease(ImageID, 40, 40, 515, 340)
else
Lib.DrawText(40, 40, 'image could not be decoded');
Lib.SaveToFile('inspection-report.pdf');
finally
Lib.Free;
end;
end;
La detección precede a la decodificación y es deliberadamente estrecha. La biblioteca lee una cabecera acotada, reconoce las marcas de formato de archivo multimedia base ISO que identifican AVIF y HEIF, y reconoce tanto la firma sin procesar como la de contenedor de JPEG XL, y después restaura la posición de flujo de quien llama. Una entrada desconocida o disfrazada nunca llega al códec externo, lo que impide que un ejecutable renombrado se entregue a un decodificador como si fuera una imagen
¿Dónde ocurre realmente la decodificación?
Los formatos de imagen modernos son códecs grandes y complejos, y meter uno dentro de una biblioteca PDF sería una decisión de diseño extraña. El backend predeterminado carga dinámicamente en proceso un módulo MagickWand desplegable y lo busca en un orden documentado: un archivo o directorio explícito que usted establezca, variables de entorno, el directorio del ejecutable y la ruta de búsqueda del sistema
Las aplicaciones que ya distribuyen un decodificador, o que no deben cargar ningún módulo externo en absoluto, registran en su lugar su propia retrollamada. El contrato es pequeño: leer el flujo de entrada, escribir un PNG en el flujo de salida, respetar la orientación solicitada:
function MyDecoder(InStream, OutPNG: TStream;
ImageFormat: TPDFlibModernImageFormat;
ApplyOrientation: Boolean): Boolean;
begin
// Decodifique InStream con su propio códec y escriba los bytes PNG en OutPNG
Result := DecodeWithBundledCodec(InStream, OutPNG,
ImageFormat, ApplyOrientation);
end;
begin
RegisterModernImageDecoderBackend(MyDecoder);
// ... añadir imágenes ...
ClearModernImageDecoderBackend; // vuelve al backend predeterminado
end;
El despliegue obtiene una comodidad y una contención deliberada. Si el directorio del códec contiene un subdirectorio modules\coders, la biblioteca rellena las variables de entorno del códec que esa disposición necesita, pero solo cuando la aplicación anfitriona todavía no las ha establecido. Una aplicación con su propia estrategia de despliegue en tiempo de ejecución la conserva
¿Por qué PNG en medio?
Pasar por un PNG en memoria en lugar de un búfer de píxeles sin procesar parece un paso extra y en realidad es el correcto más económico. PNG expresa todo lo que tiene que sobrevivir, alfa, tipo de color, profundidad de bits y un perfil ICC incrustado, y la biblioteca ya tiene una vía madura y bien probada de PNG a objeto de imagen PDF con los filtros y el espacio de color correctos. Reutilizarla significa que los formatos modernos heredan años de trabajo de corrección en lugar de recibir una implementación paralela
El puente está completamente en memoria, así que no se crean archivos temporales y no hace falta limpieza tras un fallo. Un matiz necesitó gestión explícita: algunas conversiones descartan el perfil ICC al cambiar de formato. El backend, por tanto, captura el perfil de origen antes del cambio de formato, lo comprime con Flate, construye un fragmento iCCP válido con un CRC recalculado, y elimina cualquier fragmento sRGB que entrara en conflicto con él. En las pruebas, un AVIF decodificado conservó RGBA de 16 bits con alfa de 16 bits, y el perfil extraído del PDF resultante coincidió con el perfil de origen byte a byte en 60 960 bytes
Notas prácticas antes de activarlo en producción
Compruebe la disponibilidad al arrancar en lugar de en la primera fotografía. ModernImageCodecAvailable informa de si se puede usar un backend, y SetModernImageCodecLibrary apunta a un archivo o directorio explícito cuando su despliegue coloca el códec en un lugar no estándar:
Lib.SetModernImageCodecLibrary('C:\MyApp\codecs');
if Lib.ModernImageCodecAvailable = 0 then
Log('modern image input unavailable - HEIC and AVIF will be refused');
Vigile el tamaño de archivo del resultado. Una imagen RGBA de 16 bits con un perfil incrustado es un objeto de imagen PDF grande, y un informe con cuarenta de ellas será voluminoso. Cuando el documento está destinado a visualización en pantalla más que a impresión, reducir el muestreo antes de incrustar es la decisión correcta, y las palancas generales de tamaño se tratan en la optimización del tamaño de archivo PDF
Por último, decida la política de color de forma deliberada. Conservar el perfil de origen es correcto para trabajos de archivo e impresión; convertir a un espacio a nivel de documento es correcto cuando un conjunto mixto de fotografías debe verse coherente, y la vía de conversión se describe en recolorear un documento a otro espacio de color. Si necesita confirmar qué acabó realmente en el archivo, la vía de inspección de extracción de texto, imágenes y fuentes informa de los objetos de imagen que lleva un documento
La entrada de imágenes modernas, la gestión del color y la optimización de imágenes forman parte de la misma biblioteca para Delphi, C++Builder y Free Pascal; la lista completa de funciones está en la página de PDF Library for Delphi