Anotaciones PDF

Anotaciones PDF

Page.annotations expone un AnnotationCollection — una vista mutable, similar a una secuencia, sobre cada anotación en una página. Cada entrada es un Annotation (o las subclases MarkupAnnotation / LinkAnnotation), y los datos específicos del subtipo, como puntos cuádruples, listas de tinta o colores, se leen y escriben a través de get_property() / set_property() en lugar de atributos dedicados.


Añadiendo anotaciones

AnnotationCollection.add(subtype, rect, contents, title, appearance_normal, properties) crea una nueva anotación y la agrega a la página. subtype acepta ya sea una cadena simple ("Text", "Square", "Highlight") o un miembro del enumerado AnnotationType.

import aspose_pdf
from aspose_pdf import Document, AnnotationType

doc = Document()
doc.pages.add()
page = doc.pages[0]

# Plain string subtype
page.annotations.add("Text", (100, 100, 200, 200), "Hello")

# AnnotationType enum, with subtype-specific properties
page.annotations.add(
    AnnotationType.POLYGON,
    (0, 0, 10, 10),
    "",
    properties={"Vertices": [0, 0, 10, 0, 5, 10]},
)

Lectura y actualización de propiedades

get_property(name, default) lee un valor específico del subtipo; set_property(name, value) escribe uno, y establecer una propiedad a None lo elimina del diccionario properties de la anotación.

doc = Document()
doc.pages.add()
page = doc.pages[0]

ann = page.annotations.add(
    "Square", (0, 0, 50, 50), "x", properties={"C": [1, 0, 0]},
)
ann.set_property("IC", [0, 0, 1])
print(page.annotations[0].get_property("IC"))  # [0, 0, 1]

ann.set_property("C", None)  # removes the "C" entry entirely
print("C" in page.annotations[0].properties)  # False

Nombrar anotaciones con AnnotationName

Los nombres PDF (p.ej., la entrada Name de una anotación Stamp) se marcan distintamente de las cadenas simples usando AnnotationName, una subclase str de aspose_pdf.engine.cos. Un valor almacenado de esta manera sigue siendo igual a una cadena ordinaria.

from aspose_pdf.engine.cos import AnnotationName

doc = Document()
doc.pages.add()
page = doc.pages[0]

page.annotations.add(
    "Stamp", (10, 10, 110, 60), "",
    properties={"Name": AnnotationName("Approved")},
)

Insertar, eliminar y limpiar

insert(index, subtype, rect, contents, title, appearance_normal, properties) coloca una nueva anotación en una posición específica; delete(index) elimina una por índice (generando IndexError para un índice fuera de rango); clear() elimina todas las anotaciones de la página.

doc = Document()
doc.pages.add()
page = doc.pages[0]

page.annotations.add("Text", (0, 0, 100, 100), "A")
page.annotations.add("Text", (200, 200, 300, 300), "C")
page.annotations.insert(1, "Text", (100, 100, 200, 200), "B")
# order is now: A, B, C

page.annotations.delete(1)   # removes "B"
page.annotations.clear()     # removes everything remaining

Generar apariencias de anotaciones

Annotation.generate_appearance(force) construye el flujo de apariencia /AP /N para una anotación y devuelve True cuando existe un renderizador para ese subtipo; AnnotationCollection.generate_appearances(force) hace lo mismo para cada anotación en la página en una sola llamada y devuelve el recuento de anotaciones que realmente se generaron (los subtipos no compatibles se omiten).

doc = Document()
doc.pages.add()
page = doc.pages[0]

page.annotations.add("Square", (0, 0, 50, 50), "")
page.annotations.add("Circle", (60, 0, 110, 50), "")
page.annotations.add("Text", (0, 60, 20, 80), "")  # unsupported subtype -> skipped

generated = page.annotations.generate_appearances()
print(generated)  # 2

Subtipos de anotaciones y banderas

AnnotationType enumera los nombres de subtipo estándar del PDF 32000-1:2008 (Tabla 169): TEXT, LINK, FREE_TEXT, LINE, SQUARE, CIRCLE, POLYGON, POLY_LINE, HIGHLIGHT, UNDERLINE, SQUIGGLY, STRIKE_OUT, STAMP, CARET, INK, POPUP, FILE_ATTACHMENT, SOUND, MOVIE, WIDGET, SCREEN, PRINTER_MARK, TRAP_NET, WATERMARK, y REDACT.

AnnotationFlags es un IntFlag que cubre el comportamiento de visualización/interacción de anotaciones: DEFAULT, INVISIBLE, HIDDEN, PRINT, NO_ZOOM, NO_ROTATE, NO_VIEW, READ_ONLY, LOCKED y TOGGLE_NO_VIEW.


Prelanzamiento: 3D Annotations

PDF3DAnnotation, PDF3DArtwork, PDF3DContent y PDF3DView modelan arte 3D adjunto a una página — un PDF3DAnnotation tiene un rect: Rectangle, un artwork: PDF3DArtwork y un background_color: Color opcional. PDF3DArtwork.add_view() registra un PDF3DView, cada uno lleva un render_mode (PDF3DRenderMode: SOLID, WIREFRAME, TRANSPARENT) y un lighting_scheme (PDF3DLightingScheme: HEADLAMP, WHITE, GRAY, DARK, CUSTOM). La docstring propia de la biblioteca marca PDF3DAnnotation como un “envoltorio de anotación mínima para importaciones de prelanzamiento” — trate esta superficie como una etapa temprana más que como una API de autoría 3D totalmente desarrollada.


Consejos y Mejores Prácticas

  • Prefiera los miembros del enum AnnotationType sobre cadenas de subtipo crudas cuando el valor también necesite ser comparado o ramificado en otra parte de su código.
  • Llame a set_property(name, None) para eliminar una propiedad por completo en lugar de dejar un valor obsoleto en su lugar — la entrada desaparece de properties completamente.
  • Genere apariencias por lotes con AnnotationCollection.generate_appearances en lugar de iterar generate_appearance() por anotación; devuelve el número real generado para que pueda detectar subtipos omitidos/no compatibles.
  • delete() y el indexado en page.annotations son ambos basados en 0; valide un índice antes de llamar a delete() si proviene de la entrada del usuario, ya que un índice fuera de rango lanza IndexError.
  • Envuelva los valores de nombres PDF (como el Name de un Stamp) en AnnotationName para que circulen como nombres PDF en lugar de cadenas de texto simples.

Problemas comunes

ProblemaCausaCorrección
generate_appearances() devuelve menos que el número de anotaciones añadidasUno o más subtipos no tienen un renderizador de apariencia incorporadoVerifique el recuento de retorno contra len(page.annotations); los subtipos no compatibles se omiten silenciosamente, sin generar error
delete(index) lanza IndexErrorEl índice es negativo o está más allá del recuento actual de anotacionesVerifique len(page.annotations) antes de llamar a delete()
Una propiedad establecida con set_property() no aparece después de recargarLa propiedad se estableció en None, lo que la elimina en lugar de almacenarlaUse un valor real, no None, cuando la propiedad debe persistir
La anotación insertada termina en la posición incorrectaÍndice insert(index, ...) contado desde el estado de la colección antes de la inserciónVuelva a comprobar los índices después de cada llamada a insert() en un bucle

FAQ

¿Cómo añado una anotación de comentario de texto plano?

Llame a page.annotations.add("Text", (x0, y0, x1, y1), "comment text"). La tupla de cuatro números es el rectángulo de la anotación en la página.

¿Cuál es la diferencia entre Annotation, MarkupAnnotation y LinkAnnotation?

Annotation es la vista en vivo devuelta para cualquier anotación en una página. MarkupAnnotation es la base para los subtipos de estilo marcado (highlights, text notes, shapes) y LinkAnnotation se conserva para anotaciones de estilo enlace; ambos actualmente exponen la misma superficie de métodos/propiedades que Annotation.

¿Puedo eliminar una sola propiedad sin borrar toda la anotación?

Sí — llame a annotation.set_property(name, None); la propia anotación permanece intacta, solo se elimina esa entrada de properties.

¿Falla AnnotationCollection.generate_appearances si un subtipo no es compatible?

No. Omite los subtipos sin un renderizador de apariencia incorporado y devuelve el recuento de anotaciones para las que realmente generó una apariencia.

¿Están las clases de anotación 3D listas para producción?

PDF3DAnnotation y los tipos relacionados están documentados como un contenedor mínimo para importaciones prerelease — verifique el comportamiento en su visor de PDF objetivo antes de confiar en ellos para contenido 3D de producción.


Resumen de API Reference

Clase/MétodoDescripción
AnnotationCollection.addCrear y añadir una nueva anotación a una página
AnnotationCollection.insertCrear e insertar una nueva anotación en un índice específico
AnnotationCollection.deleteEliminar una anotación por índice (lanza IndexError si está fuera de rango)
AnnotationCollection.clearEliminar todas las anotaciones de la página
AnnotationCollection.generate_appearancesGenerar flujos de apariencia /AP /N para cada anotación compatible en la página
Annotation.get_property / set_propertyLeer o escribir un valor de propiedad específico del subtipo
Annotation.update_propertiesRecalcular el estado derivado después de ediciones directas de propiedades
Annotation.generate_appearanceGenerar el flujo de apariencia /AP /N para una única anotación
AnnotationTypeEnumeración de nombres de subtipos de anotación PDF estándar
AnnotationFlagsIntFlag del comportamiento de visualización/interacción de la anotación
AnnotationNamestr subclase que marca un valor para serializarlo como un nombre PDF
PDF3DAnnotation / PDF3DArtwork / PDF3DContent / PDF3DViewModelo de anotación y obra de arte 3D en pre-lanzamiento
PDF3DRenderMode / PDF3DLightingSchemeEnums para el modo de renderizado de vista 3D y el esquema de iluminación

Ver también

 Español