Trabajar con filtros SVG en Python

Respuesta rápida: Para trabajar con filtros SVG en Python, cargue el SVG con SVGDocument, encuentre el elemento de destino con query_selector(), establezca su atributo filter con set_attribute() y guarde el SVG.

1from aspose.svg import SVGDocument
2
3with SVGDocument("document.svg") as document:
4    element = document.root_element.query_selector("circle")
5    if element is not None:
6        element.set_attribute("filter", "url(#filter-id)")
7    document.save("filtered.svg")

Los filtros SVG crean efectos visuales como desenfoque, sombra, resplandor, iluminación y procesamiento de color. Un filtro suele definirse dentro de <defs> y aplicarse a un elemento visible mediante un atributo filter="url(#filter-id)". En Aspose.SVG for Python via .NET, trabaja con filtros mediante el DOM SVG: encuentra elementos de destino, crea primitivas de filtro, establece atributos, añade nodos y guarda el archivo editado.

En este artículo aprenderá a:

Conceptos básicos de edición de filtros SVG

Un flujo de filtro tiene dos partes: la definición del filtro y la referencia al filtro. La definición vive en <defs>, mientras que el elemento visible apunta a ella por ID.

TareaMarcado SVG que se editaPatrón típico de API
Aplicar un filtro existentefilter="url(#filter-id)"Encontrar el elemento visible con query_selector() y establecer el atributo filter
Crear un filtro nuevo<defs><filter id="..."></filter></defs>Crear elementos SVG con create_element_ns() y añadirlos con append_child()
Configurar desenfoque o sombraAtributos de primitivas de filtro como stdDeviation, dx, dy, flood-colorEncontrar la primitiva y actualizar atributos
Eliminar un efectoAtributo filter en el elemento visibleEliminar la referencia de filtro con remove_attribute()

Cómo aplicar filtros SVG en Python

Use este flujo cuando un archivo SVG necesite desenfoque, sombra, resplandor u otro efecto de filtro:

  1. Cargue el archivo SVG con SVGDocument.
  2. Encuentre o cree el elemento <defs> que almacena definiciones reutilizables.
  3. Encuentre o cree un elemento <filter> con un id estable.
  4. Añada o actualice primitivas de filtro como <feGaussianBlur>, <feOffset> o <feDropShadow>.
  5. Aplique el filtro a un elemento SVG visible con filter="url(#filter-id)".
  6. Guarde el SVG editado y compruebe la salida renderizada.

Los ejemplos siguientes usan svg-filters.svg como archivo de entrada.

Crear y aplicar un filtro de desenfoque

Un filtro debe definirse antes de que un elemento visible pueda usarlo. El ejemplo siguiente crea un filtro #blur en <defs>, añade una primitiva <feGaussianBlur>, aplica el filtro al círculo y guarda el resultado como svg-blur-filter-applied.svg.

 1import os
 2from aspose.svg import SVGDocument
 3
 4SVG_NS = "http://www.w3.org/2000/svg"
 5
 6input_folder = "data/"
 7output_folder = "output/"
 8input_path = os.path.join(input_folder, "svg-filters.svg")
 9output_path = os.path.join(output_folder, "svg-blur-filter-applied.svg")
10os.makedirs(output_folder, exist_ok=True)
11
12with SVGDocument(input_path) as document:
13    svg = document.root_element
14    defs = svg.query_selector("defs")
15
16    if defs is None:
17        defs = document.create_element_ns(SVG_NS, "defs")
18        svg.insert_before(defs, svg.first_child)
19
20    blur_filter = document.create_element_ns(SVG_NS, "filter")
21    blur_filter.set_attribute("id", "blur")
22    blur_filter.set_attribute("x", "-20%")
23    blur_filter.set_attribute("y", "-20%")
24    blur_filter.set_attribute("width", "140%")
25    blur_filter.set_attribute("height", "140%")
26
27    gaussian_blur = document.create_element_ns(SVG_NS, "feGaussianBlur")
28    gaussian_blur.set_attribute("in", "SourceGraphic")
29    gaussian_blur.set_attribute("stdDeviation", "3")
30
31    blur_filter.append_child(gaussian_blur)
32    defs.append_child(blur_filter)
33
34    circle = svg.query_selector("circle")
35    if circle is not None:
36        circle.set_attribute("filter", "url(#blur)")
37
38    document.save(output_path)

El código muestra las dos partes necesarias de un flujo de filtro SVG. Los elementos <filter> y <feGaussianBlur> definen el efecto, y el atributo filter="url(#blur)" aplica ese efecto al círculo visible. La ilustración compara el SVG de origen en la imagen (a) con el círculo desenfocado en la imagen (b).

Círculo y texto SVG originales comparados con un círculo desenfocado por un filtro Gaussian blur en Python

Crear un filtro de sombra

Cree un filtro nuevo cuando el SVG todavía no contenga el efecto que necesita. El ejemplo siguiente crea un filtro #label-shadow con <feDropShadow>, lo añade a <defs> y lo aplica a la etiqueta de texto.

 1import os
 2from aspose.svg import SVGDocument
 3
 4SVG_NS = "http://www.w3.org/2000/svg"
 5
 6input_folder = "data/"
 7output_folder = "output/"
 8input_path = os.path.join(input_folder, "svg-filters.svg")
 9output_path = os.path.join(output_folder, "svg-drop-shadow-filter.svg")
10os.makedirs(output_folder, exist_ok=True)
11
12with SVGDocument(input_path) as document:
13    svg = document.root_element
14    defs = svg.query_selector("defs")
15
16    if defs is None:
17        defs = document.create_element_ns(SVG_NS, "defs")
18        svg.insert_before(defs, svg.first_child)
19
20    shadow_filter = document.create_element_ns(SVG_NS, "filter")
21    shadow_filter.set_attribute("id", "label-shadow")
22    shadow_filter.set_attribute("x", "-20%")
23    shadow_filter.set_attribute("y", "-20%")
24    shadow_filter.set_attribute("width", "150%")
25    shadow_filter.set_attribute("height", "150%")
26
27    drop_shadow = document.create_element_ns(SVG_NS, "feDropShadow")
28    drop_shadow.set_attribute("dx", "6")
29    drop_shadow.set_attribute("dy", "8")
30    drop_shadow.set_attribute("stdDeviation", "2")
31    drop_shadow.set_attribute("flood-color", "#455a64")
32    drop_shadow.set_attribute("flood-opacity", "0.6")
33
34    shadow_filter.append_child(drop_shadow)
35    defs.append_child(shadow_filter)
36
37    label = svg.query_selector("#label")
38    if label is not None:
39        label.set_attribute("filter", "url(#label-shadow)")
40
41    document.save(output_path)

Este ejemplo muestra las dos partes del flujo de filtro: el filtro reutilizable se crea en <defs> y el elemento de texto visible recibe filter="url(#label-shadow)". Si falta una de las dos partes, la sombra no aparecerá. La ilustración muestra la etiqueta original en la imagen (a) y la misma etiqueta con sombra en la imagen (b).

Texto SVG original comparado con texto SVG después de añadir un filtro de sombra en Python

Editar atributos de un filtro existente

Los efectos de filtro se controlan mediante atributos en primitivas de filtro. El ejemplo siguiente abre el SVG creado por el ejemplo de desenfoque, encuentra <feGaussianBlur> dentro de #blur y aumenta su valor stdDeviation.

 1import os
 2from aspose.svg import SVGDocument
 3
 4input_folder = "output/"
 5output_folder = "output/"
 6input_path = os.path.join(input_folder, "svg-blur-filter-applied.svg")
 7output_path = os.path.join(output_folder, "svg-filter-attributes-edited.svg")
 8os.makedirs(output_folder, exist_ok=True)
 9
10with SVGDocument(input_path) as document:
11    svg = document.root_element
12    blur = svg.query_selector("#blur feGaussianBlur")
13
14    if blur is not None:
15        blur.set_attribute("stdDeviation", "8")
16
17    document.save(output_path)

La salida usa el mismo ID de filtro, pero el desenfoque es más fuerte porque el valor stdDeviation cambió de 3 a 8. La ilustración compara el primer resultado de desenfoque en la imagen (a) con el desenfoque más fuerte después de editar la primitiva de filtro en la imagen (b).

Resultado SVG Gaussian blur comparado con un desenfoque más fuerte tras editar stdDeviation en Python

Eliminar un filtro de un elemento SVG

Eliminar un filtro de un elemento visible es distinto de borrar la definición del filtro. El siguiente ejemplo abre el SVG creado por el ejemplo de desenfoque y elimina solo la referencia filter del círculo; la definición #blur puede permanecer en <defs> para reutilizarse.

 1import os
 2from aspose.svg import SVGDocument
 3
 4input_folder = "output/"
 5output_folder = "output/"
 6input_path = os.path.join(input_folder, "svg-blur-filter-applied.svg")
 7output_path = os.path.join(output_folder, "svg-filter-removed.svg")
 8os.makedirs(output_folder, exist_ok=True)
 9
10with SVGDocument(input_path) as document:
11    circle = document.root_element.query_selector("circle")
12
13    if circle is not None and circle.has_attribute("filter"):
14        circle.remove_attribute("filter")
15
16    document.save(output_path)

Use este patrón cuando un filtro ya no deba afectar a un elemento específico, pero otros elementos aún puedan usar la misma definición de filtro.

Errores comunes y soluciones

ProblemaSolución
El filtro no apareceAsegúrese de que el elemento visible tenga filter="url(#filter-id)" y de que ese ID exista en <defs>
La sombra o el desenfoque se recortaAumente la región del filtro con x, y, width y height en <filter>
El filtro afecta al elemento equivocadoAplique el atributo filter a la forma o grupo visible que debe recibir el efecto
Editar fill o stroke no cambia el efectoActualice atributos de la primitiva de filtro, como stdDeviation, flood-color, dx o dy
IDs de filtro duplicados causan una salida confusaUse IDs estables y únicos, y actualice las referencias url(#...) para que coincidan
El archivo de salida no cambióGuarde el documento editado y abra la ruta de salida, no el SVG de entrada

FAQ

¿Cómo aplico un filtro SVG en Python?

Cargue el SVG con SVGDocument, encuentre el elemento visible de destino y establezca filter="url(#filter-id)" con set_attribute(). El <filter> referenciado debe existir en el documento SVG, normalmente dentro de <defs>.

¿Cómo creo un filtro SVG de desenfoque?

Cree un elemento <filter> en <defs>, añada la primitiva <feGaussianBlur>, establezca stdDeviation y luego aplique el filtro a un elemento visible con filter="url(#filter-id)".

¿Cómo añado una sombra a SVG en Python?

Cree un filtro con una primitiva de sombra como <feDropShadow>, establezca atributos como dx, dy, stdDeviation y flood-color, añada el filtro a <defs> y aplíquelo con filter="url(#filter-id)".

¿Puedo editar atributos de filtros SVG existentes?

Sí. Encuentre la primitiva de filtro, por ejemplo #blur feGaussianBlur, y actualice atributos como stdDeviation. Guarde el SVG después del cambio.

¿Puedo quitar un filtro sin eliminarlo de defs?

Sí. Elimine el atributo filter del elemento visible. La definición <filter> puede permanecer en <defs> si otros elementos aún la usan o si quiere reutilizarla más adelante.

Artículos relacionados