Files
fn_registry/python/functions/infra/pdf_add_image.py
T
egutierrez 0819c35bbb feat: issue/0020 — generacion de PDFs en Python y Go
Añade 3 tipos Python (PDFDoc, PDFPage, PDFStyle) y 10 funciones Python
para construir PDFs con fpdf2 (builder fluent), fusionar PDFs con pypdf
y convertir HTML/Markdown a PDF via weasyprint (stub si no disponible).
Añade pdf_simple_report en Go como stub hasta que go-pdf/fpdf se integre.

- python/types/infra/: pdf_doc, pdf_page, pdf_style
- python/functions/infra/: pdf_create, pdf_add_page, pdf_add_text,
  pdf_add_table, pdf_add_image, pdf_add_header_footer, pdf_from_html,
  pdf_from_markdown, pdf_merge, pdf_save
- functions/infra/pdf_simple_report.go: stub Go con ReportSection/ReportTable
- 17 tests Python pasando (pytest)
- fpdf2 y pypdf añadidos via uv al venv Python

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 02:02:51 +02:00

58 lines
1.9 KiB
Python

"""pdf_add_image — añade una imagen al documento PDF desde path o bytes."""
import io
import sys
import os
_types_dir = os.path.join(os.path.dirname(__file__), "..", "..", "..", "python", "types", "infra")
sys.path.insert(0, _types_dir)
from pdf_doc import PDFDoc
def pdf_add_image(
doc: PDFDoc,
image: str | bytes,
x: float | None = None,
y: float | None = None,
width: float | None = None,
height: float | None = None,
keep_aspect: bool = True,
) -> PDFDoc:
"""Añade una imagen al documento PDF desde un path de archivo o bytes.
Si solo se especifica width, la altura se calcula manteniendo el ratio.
Si solo se especifica height, el ancho se calcula manteniendo el ratio.
Si ninguno se especifica, se usa el ancho disponible entre margenes.
Args:
doc: PDFDoc con pagina activa.
image: path absoluto o relativo a la imagen, o bytes del contenido.
x: posicion X en mm. None usa la posicion actual del cursor.
y: posicion Y en mm. None usa la posicion actual del cursor.
width: ancho de la imagen en mm. None calcula desde height o usa ancho disponible.
height: alto de la imagen en mm. None calcula desde width.
keep_aspect: si True mantiene la relacion de aspecto (siempre aplicable con fpdf2).
Returns:
PDFDoc con la imagen añadida.
"""
fpdf = doc.fpdf
cur_x = x if x is not None else fpdf.get_x()
cur_y = y if y is not None else fpdf.get_y()
# Ancho por defecto: ancho disponible
img_width = width if width is not None else (fpdf.epw if height is None else 0)
img_height = height if height is not None else 0
if isinstance(image, bytes):
img_io = io.BytesIO(image)
fpdf.image(img_io, x=cur_x, y=cur_y, w=img_width, h=img_height)
else:
fpdf.image(image, x=cur_x, y=cur_y, w=img_width, h=img_height)
# Mover cursor debajo de la imagen
fpdf.ln(5)
return doc