Personalizza forme di presentazione in Python

Panoramica

Questo articolo spiega come personalizzare le forme delle presentazioni in Aspose.Slides modificando la geometria delle forme tramite i punti di modifica e i percorsi geometrici. Mostra come lavorare con GeometryPath per modificare le forme esistenti, eseguire operazioni di base di modifica del percorso, aggiungere o rimuovere punti e applicare la geometria aggiornata a una forma.

Dimostra inoltre come creare forme personalizzate e composite, costruire forme con angoli curvi, determinare se la geometria di una forma è chiusa e estrarre gli elementi della forma per l’analisi del contorno.

Modifica una Forma usando i Punti di Modifica

In PowerPoint, puoi usare Edit Points per modificare un quadrato:

  • Spostare un angolo verso l’interno o verso l’esterno.
  • Regolare la curvatura in un punto.
  • Aggiungere nuovi punti.

Modificare i punti consente di modificare il contorno di una forma o di utilizzare una forma esistente come base per una nuova.

Suggerimenti per la Modifica delle Forme

overview_image

Durante la modifica delle forme PowerPoint, tenere a mente questi concetti:

  • Una forma (o il suo percorso) può essere chiusa o aperta.
  • Il percorso di una forma è costituito da punti di ancoraggio collegati da segmenti.
  • Un segmento può essere rettilineo o curvo. I punti di ancoraggio e le maniglie di controllo determinano la sua forma.
  • I punti di ancoraggio possono essere punti d’angolo, punti rettilinei o punti lisci:
    • In un punto d’angolo, i segmenti adiacenti possono incontrarsi formando un angolo.
    • In un punto liscio, le due maniglie di controllo sono allineate e alla stessa distanza dal punto di ancoraggio.
    • In un punto retto, le due maniglie di controllo sono allineate ma possono trovarsi a distanze diverse dal punto di ancoraggio.
  • Spostare i punti di ancoraggio o regolare le loro maniglie cambia il contorno della forma.

Per modificare le forme PowerPoint tramite i punti di modifica, Aspose.Slides fornisce la classe GeometryPath.

Operazioni di Modifica Semplici

Utilizzare i seguenti metodi per modificare un percorso geometrico. Le overload che accettano un indice inseriscono un segmento in quella posizione basata su zero nell’array dei segmenti del percorso.

Operazione Metodo
Aggiungere o inserire una linea retta. GeometryPath.line_to
Aggiungere o inserire una curva Bézier cubica con due punti di controllo e un punto finale. GeometryPath.cubic_bezier_to
Aggiungere o inserire una curva Bézier quadratica con un punto di controllo e un punto finale. GeometryPath.quadratic_bezier_to
Aggiungere un arco ellittico con le dimensioni e gli angoli specificati in gradi. GeometryPath.arc_to
Chiudere la figura corrente collegando il suo punto finale al punto di partenza. GeometryPath.close_figure
Impostare il punto di partenza di una figura. GeometryPath.move_to
Rimuovere un segmento a indice zero-base. GeometryPath.remove_at

Aggiungere Punti Personalizzati a una Forma

Questo esempio inserisce due punti in una forma rettangolare usando GeometryPath.line_to e applica il percorso modificato con GeometryShape.set_geometry_path. Le coordinate sono locali alla forma: entrambi i nuovi punti sono al suo centro, a 100 punti dal lato sinistro e 50 punti dall’alto. Gli indici dei segmenti 1 e 4 li posizionano sui bordi superiore e inferiore, tirando questi bordi verso l’interno.

import aspose.slides as slides

with slides.Presentation() as presentation:
    slide = presentation.slides[0]

    shape = slide.shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 100, 100, 200, 100)

    geometry_path = shape.get_geometry_paths()[0]
    geometry_path.line_to(100, 50, 1)
    geometry_path.line_to(100, 50, 4)

    shape.set_geometry_path(geometry_path)

example1_image

Rimuovere Punti da una Forma

Questo esempio modifica il contorno di una forma a cuore rimuovendo il segmento all’indice zero‑base 2 con GeometryPath.remove_at. L’applicazione del percorso modificato con GeometryShape.set_geometry_path aggiorna il contorno della forma.

import aspose.slides as slides

with slides.Presentation() as presentation:
    slide = presentation.slides[0]

    shape = slide.shapes.add_auto_shape(slides.ShapeType.HEART, 100, 100, 300, 300)

    path = shape.get_geometry_paths()[0]
    path.remove_at(2)

    shape.set_geometry_path(path)

example2_image

Creare una Forma Personalizzata

Questo esempio costruisce una stella a cinque punte con GeometryPath. Raggi esterni e interni alternati di 100 e 50 punti definiscono le punte e le rientranze; un passo di 72 gradi distribuisce uniformemente le cinque punte. Il percorso è chiuso con GeometryPath.close_figure e applicato a una forma rettangolare usando GeometryShape.set_geometry_path, sostituendo il suo contorno.

import aspose.slides as slides
import aspose.pydrawing as draw
import math

points = []

outer_radius = 100
inner_radius = 50
angle_step = 72

for angle in range(-90, 270, angle_step):
    radians = angle * (math.pi / 180)
    x = outer_radius * math.cos(radians)
    y = outer_radius * math.sin(radians)
    points.append(slides.PointF(x + outer_radius, y + outer_radius))

    radians = math.pi * (angle + angle_step / 2) / 180.0
    x = inner_radius * math.cos(radians)
    y = inner_radius * math.sin(radians)
    points.append(slides.PointF(x + outer_radius, y + outer_radius))

star_path = slides.GeometryPath()
star_path.move_to(points[0])

for i in range(1, len(points)):
    star_path.line_to(points[i])

star_path.close_figure()

with slides.Presentation() as presentation:
    slide = presentation.slides[0]

    shape = slide.shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 100, 100, outer_radius * 2, outer_radius * 2)
    shape.set_geometry_path(star_path)

example3_image

Creare una Forma Personalizzata Composita

Questo esempio definisce due oggetti GeometryPath chiusi per il terzo superiore e inferiore di una forma. L’applicazione di entrambi i percorsi con GeometryShape.set_geometry_paths crea un’unica forma composita con uno spazio al centro del terzo medio.

import aspose.slides as slides

with slides.Presentation() as presentation:
    slide = presentation.slides[0]

    shape = slide.shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 100, 100, 200, 100)

    top_path = slides.GeometryPath()
    top_path.move_to(0, 0)
    top_path.line_to(shape.width, 0)
    top_path.line_to(shape.width, shape.height / 3)
    top_path.line_to(0, shape.height / 3)
    top_path.close_figure()

    bottom_path = slides.GeometryPath()
    bottom_path.move_to(0, shape.height / 3 * 2)
    bottom_path.line_to(shape.width, shape.height / 3 * 2)
    bottom_path.line_to(shape.width, shape.height)
    bottom_path.line_to(0, shape.height)
    bottom_path.close_figure()

    shape.set_geometry_paths([top_path, bottom_path])

example4_image

Creare una Forma Personalizzata con Angoli Curvi

Questo esempio combina segmenti rettilinei con GeometryPath.arc_to per creare una forma con angoli curvi verso l’interno. La dimensione di ciascun angolo imposta la larghezza e l’altezza dell’arco in punti, e la sweep di -90 gradi disegna un quarto di ellisse in senso antiorario. Il percorso completato è applicato con GeometryShape.set_geometry_path, e la presentazione viene salvata in formato PPTX.

import aspose.slides as slides
import aspose.pydrawing as draw

shape_x = 20
shape_y = 20
shape_width = 300
shape_height = 200

left_top_size = 50
right_top_size = 20
right_bottom_size = 40
left_bottom_size = 10

with slides.Presentation() as presentation:
    slide = presentation.slides[0]

    shape = slide.shapes.add_auto_shape(slides.ShapeType.CUSTOM, shape_x, shape_y, shape_width, shape_height)

    top_left = slides.PointF(left_top_size, 0)
    top_right = slides.PointF(shape_width - right_top_size, 0)
    right_bottom = slides.PointF(shape_width, shape_height - right_bottom_size)
    bottom_left = slides.PointF(left_bottom_size, shape_height)
    left_top = slides.PointF(0, left_top_size)

    geometry_path = slides.GeometryPath()
    geometry_path.move_to(top_left)
    geometry_path.line_to(top_right)
    geometry_path.arc_to(right_top_size, right_top_size, 180, -90)
    geometry_path.line_to(right_bottom)
    geometry_path.arc_to(right_bottom_size, right_bottom_size, -90, -90)
    geometry_path.line_to(bottom_left)
    geometry_path.arc_to(left_bottom_size, left_bottom_size, 0, -90)
    geometry_path.line_to(left_top)
    geometry_path.arc_to(left_top_size, left_top_size, 90, -90)
    geometry_path.close_figure()

    shape.set_geometry_path(geometry_path)

    presentation.save("output.pptx", slides.export.SaveFormat.PPTX)

Scoprire se la Geometria di una Forma è Chiusa

Il seguente helper verifica se ogni percorso geometrico non vuoto termina con un segmento di chiusura. Legge GeometryPath.path_data e confronta il PathSegment.path_command finale con PathCommandType.CLOSE. Restituisce false quando non ci sono percorsi non vuoti. Questa verifica il comando finale di ogni percorso; non ispeziona ogni sotto‑figura all’interno di un percorso. L’esempio stampa True per un rettangolo.

import aspose.slides as slides


def is_geometry_closed(geometry_shape):
    has_nonempty_path = False

    for geometry_path in geometry_shape.get_geometry_paths():
        segments = geometry_path.path_data
        if len(segments) == 0:
            continue

        has_nonempty_path = True
        last_segment = segments[len(segments) - 1]
        if last_segment.path_command != slides.PathCommandType.CLOSE:
            return False

    return has_nonempty_path


with slides.Presentation() as presentation:
    slide = presentation.slides[0]
    shape = slide.shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 100, 100, 200, 100)
    print(is_geometry_closed(shape))

Estrarre e Ispezionare gli Elementi della Forma

Usa GeometryShape.create_shape_elements per ispezionare una forma esistente come elementi contenenti punti di percorso e tipi di punto. Ogni ShapeElement restituito espone i suoi array path_points e path_types. Questa rappresentazione è utile per l’analisi del contorno o per passare la geometria a strumenti di disegno personalizzati.

L’esempio apre una presentazione, trova la prima forma geometrica direttamente sulla prima diapositiva e stampa i suoi segmenti di percorso. Usa una presentazione contenente una forma con segmenti rettilinei e curvi per vedere entrambi i tipi di output. Non ricerca all’interno dei gruppi.

import aspose.slides as slides

with slides.Presentation("input.pptx") as presentation:
    slide = presentation.slides[0]
    shape = next((item for item in slide.shapes if isinstance(item, slides.GeometryShape)), None)

    if shape is None:
        print("No geometry shape found on the first slide.")
    else:
        for element in shape.create_shape_elements():
            points = element.path_points
            types = element.path_types
            print("Shape element:")

            i = 0
            while i < len(points):
                point_type = types[i] & 0x07  # Keep the segment type, excluding flags.
                if point_type == 0:
                    print(f"Start figure at {points[i]}")
                elif point_type == 1:
                    print(f"Line to {points[i]}")
                elif point_type == 3:
                    print(f"Cubic Bezier: controls {points[i]}, {points[i + 1]}; end {points[i + 2]}")
                    i += 2  # Consume both control points and the endpoint.

                if (types[i] & 0x80) != 0:
                    print("Close subpath back to its starting point.")
                i += 1

Gli array corrispondono per indice: points[i] è un punto e types[i] ne descrive il ruolo. Il tipo 0 avvia una figura, e il tipo 1 disegna una linea dal punto precedente al punto corrente. Un segmento Bézier cubico inizia dal punto finale precedente e utilizza tre voci consecutive di tipo 3: due punti di controllo seguiti dal nuovo punto finale. Il ciclo consuma queste tre voci insieme e verifica il punto finale per la chiusura.

I tipi di punto contengono anche flag. Mascherare con 0x07 per identificare il tipo di segmento e testare 0x80 separatamente per rilevare un sotto‑percorso chiuso. Per esempio, 129 (0x81) indica un punto finale di linea che chiude un sotto‑percorso, e 131 (0x83) indica un punto finale Bézier che ne chiude uno. Confrontare il valore grezzo solo con 1 o 3 farebbe perdere questi casi. Altri flag, come dash (0x10) e marker (0x20), non cambiano il tipo base del segmento.

Coordinate e trasformazioni. I punti sono misurati in punti (1/72 di pollice), con X che aumenta verso destra e Y che aumenta verso il basso. Per una forma non raggruppata, le coordinate estratte includono già la sua posizione x e y e riflettono la sua larghezza e altezza attuali. Per esempio, un rettangolo non ruotato a (100, 200) con dimensioni 120 × 80 ha i bordi del contorno (100, 200)–(220, 280). Non aggiungere nuovamente la posizione della forma. Sottrai il suo X e Y per ottenere coordinate relative al suo frame non ruotato.

I punti estratti non applicano la rotation della forma né i ribaltamenti orizzontali e verticali. Per riprodurre il contorno visualizzato, applica quelle trasformazioni intorno al centro della forma. Per forme raggruppate, tieni conto anche della mappatura delle coordinate del gruppo e delle trasformazioni; non presumere che i punti estratti siano le coordinate finali renderizzate della diapositiva né applicare una traslazione o scala due volte se è già riflessa nel frame del figlio.

Ispezione rispetto alla modifica. Gli array estratti descrivono il contorno; modificarli non aggiorna la forma originale. Scegli questo approccio quando la tua analisi o il tuo codice di disegno richiedono array punto/tipo. Usa get_geometry_paths quando ti servono i comandi di geometria nel sistema di coordinate locale della forma o quando vuoi modificare la sua geometria. Applica i percorsi modificati tramite set_geometry_path o set_geometry_paths.

FAQ

Cosa succederà al riempimento e al contorno dopo aver sostituito la geometria?

Lo stile rimane associato alla forma; solo il contorno cambia. Il riempimento e il contorno vengono applicati automaticamente alla nuova geometria.

Come ruoto correttamente una forma personalizzata insieme alla sua geometria?

Usa la proprietà rotation della forma; la geometria ruota con la forma perché è legata al proprio sistema di coordinate.

Posso convertire una forma personalizzata in un’immagine per “bloccare” il risultato?

Sì. Esporta l’area della slide richiesta o la shape stessa in un formato raster; questo semplifica ulteriori lavori con geometrie complesse.