Personnaliser les formes de présentation sur Android
Vue d’ensemble
Cet article explique comment personnaliser les formes de présentation dans Aspose.Slides en modifiant la géométrie des formes via les points d’édition et les chemins de géométrie. Il montre comment travailler avec GeometryPath et IGeometryPath pour modifier des formes existantes, effectuer des opérations de base d’édition de chemin, ajouter ou supprimer des points et appliquer la géométrie mise à jour à une forme.
Il montre également comment créer des formes personnalisées et composites, construire des formes avec des coins arrondis, déterminer si une géométrie de forme est fermée et inspecter les éléments de forme à l’aide de tableaux de points Android.
Modifier une forme à l’aide de points d’édition
Dans PowerPoint, vous pouvez utiliser Points d’édition pour modifier un carré :
- Déplacer un coin vers l’intérieur ou l’extérieur.
- Ajuster la courbure d’un point.
- Ajouter de nouveaux points.
La modification des points vous permet de changer le contour d’une forme ou d’utiliser une forme existante comme base pour une nouvelle.
Conseils de modification de forme

Lors de la modification des formes PowerPoint, gardez ces concepts à l’esprit :
- Une forme (ou son chemin) peut être fermée ou ouverte.
- Le chemin d’une forme se compose de points d’ancrage reliés par des segments.
- Un segment peut être droit ou courbe. Les points d’ancrage et les poignées de contrôle déterminent sa forme.
- Les points d’ancrage existent sous forme de points de coin, de points droits ou de points lisses :
- À un point de coin, les segments adjacents peuvent se rejoindre sous un angle.
- À un point lisse, les deux poignées de contrôle sont alignées et à égale distance du point d’ancrage.
- À un point droit, les deux poignées de contrôle sont alignées mais peuvent être à des distances différentes du point d’ancrage.
- Déplacer les points d’ancrage ou ajuster leurs poignées modifie le contour de la forme.
Pour modifier les formes PowerPoint via les points d’édition, Aspose.Slides fournit la classe GeometryPath et l’interface IGeometryPath.
- Une instance de GeometryPath représente le chemin de géométrie de l’objet IGeometryShape.
- Pour récupérer le GeometryPath depuis l’instance IGeometryShape, utilisez la méthode IGeometryShape.getGeometryPaths .
- Pour définir le GeometryPath d’une forme, utilisez ces méthodes : IGeometryShape.setGeometryPath pour les formes à chemin unique et IGeometryShape.setGeometryPaths pour les formes à plusieurs chemins.
- Pour ajouter des segments, utilisez les méthodes de IGeometryPath .
- En utilisant les méthodes IGeometryPath.setStroke et IGeometryPath.setFillMode, vous pouvez définir l’apparence d’un chemin de géométrie.
- En appelant la méthode IGeometryPath.getPathData , vous pouvez récupérer le chemin de géométrie d’un GeometryShape sous forme de tableau de segments de chemin.
Opérations d’édition simples
Utilisez les méthodes suivantes pour éditer un chemin de géométrie. Les surcharges qui acceptent un indice insèrent un segment à cette position zéro‑based dans le tableau de segments du chemin.
| Opération | Méthode |
|---|---|
| Ajouter ou insérer une ligne droite. | GeometryPath.lineTo |
| Ajouter ou insérer une courbe de Bézier cubique avec deux points de contrôle et un point final. | GeometryPath.cubicBezierTo |
| Ajouter ou insérer une courbe de Bézier quadratique avec un point de contrôle et un point final. | GeometryPath.quadraticBezierTo |
| Ajouter un arc elliptique avec les dimensions et angles spécifiés en degrés. | GeometryPath.arcTo |
| Fermer la figure courante en reliant son point final à son point de départ. | GeometryPath.closeFigure |
| Définir le point de départ d’une figure. | GeometryPath.moveTo |
| Supprimer un segment à un indice zéro‑based. | GeometryPath.removeAt |
Ajouter des points personnalisés à une forme
Cet exemple insère deux points dans une forme rectangulaire en utilisant GeometryPath.lineTo et applique le chemin modifié avec IGeometryShape.setGeometryPath. Les coordonnées sont locales à la forme : les deux nouveaux points sont au centre, à 100 points du bord gauche et 50 points du bord supérieur. Les indices de segment 1 et 4 les placent respectivement sur les bords supérieur et inférieur, tirant ces bords vers l’intérieur.
import com.aspose.slides.*;
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 100, 100, 200, 100);
IGeometryPath geometryPath = shape.getGeometryPaths()[0];
geometryPath.lineTo(100, 50, 1);
geometryPath.lineTo(100, 50, 4);
shape.setGeometryPath(geometryPath);
} finally {
presentation.dispose();
}

Supprimer des points d’une forme
Cet exemple modifie le contour d’une forme en cœur en supprimant le segment à l’indice zéro‑based 2 avec GeometryPath.removeAt. L’application du chemin modifié avec IGeometryShape.setGeometryPath met à jour le contour de la forme.
import com.aspose.slides.*;
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape shape = slide.getShapes().addAutoShape(ShapeType.Heart, 100, 100, 300, 300);
IGeometryPath path = shape.getGeometryPaths()[0];
path.removeAt(2);
shape.setGeometryPath(path);
} finally {
presentation.dispose();
}

Créer une forme personnalisée
Cet exemple construit une étoile à cinq branches avec GeometryPath. Des rayons extérieurs et intérieurs alternés de 100 et 50 points définissent les pointes et les encoches ; un pas de 72 degrés espace uniformément les cinq pointes. Le chemin est fermé avec GeometryPath.closeFigure et appliqué à une forme rectangulaire via IGeometryShape.setGeometryPath, remplaçant son contour.
import com.aspose.slides.*;
import android.graphics.PointF;
import java.util.ArrayList;
import java.util.List;
List<PointF> points = new ArrayList<>();
float outerRadius = 100f;
float innerRadius = 50f;
int angleStep = 72;
for (int angle = -90; angle < 270; angle += angleStep)
{
double radians = angle * (Math.PI / 180f);
double x = outerRadius * Math.cos(radians);
double y = outerRadius * Math.sin(radians);
PointF point = new PointF((float)x + outerRadius, (float)y + outerRadius);
points.add(point);
radians = Math.PI * (angle + angleStep / 2) / 180.0;
x = innerRadius * Math.cos(radians);
y = innerRadius * Math.sin(radians);
point = new PointF((float)x + outerRadius, (float)y + outerRadius);
points.add(point);
}
GeometryPath starPath = new GeometryPath();
starPath.moveTo(points.get(0));
for (int i = 1; i < points.size(); i++)
{
starPath.lineTo(points.get(i));
}
starPath.closeFigure();
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 100, 100, outerRadius * 2, outerRadius * 2);
shape.setGeometryPath(starPath);
} finally {
presentation.dispose();
}

Créer une forme composite personnalisée
Cet exemple définit deux GeometryPath fermés pour le tiers supérieur et le tiers inférieur d’une forme. L’application des deux chemins avec IGeometryShape.setGeometryPaths crée une seule forme composite avec un espace au milieu du troisième supérieur.
import com.aspose.slides.*;
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 100, 100, 200, 100);
GeometryPath topPath = new GeometryPath();
topPath.moveTo(0, 0);
topPath.lineTo(shape.getWidth(), 0);
topPath.lineTo(shape.getWidth(), shape.getHeight() / 3);
topPath.lineTo(0, shape.getHeight() / 3);
topPath.closeFigure();
GeometryPath bottomPath = new GeometryPath();
bottomPath.moveTo(0, shape.getHeight() / 3 * 2);
bottomPath.lineTo(shape.getWidth(), shape.getHeight() / 3 * 2);
bottomPath.lineTo(shape.getWidth(), shape.getHeight());
bottomPath.lineTo(0, shape.getHeight());
bottomPath.closeFigure();
shape.setGeometryPaths(new GeometryPath[] { topPath, bottomPath });
} finally {
presentation.dispose();
}

Créer une forme personnalisée avec des coins arrondis
Cet exemple combine des segments droits avec GeometryPath.arcTo pour créer une forme aux coins incurvés vers l’intérieur. Chaque taille de coin définit la largeur et la hauteur de l’arc en points, et le balayage de -90 degrés trace un quart d’ellipse dans le sens antihoraire. Le chemin complet est appliqué avec IGeometryShape.setGeometryPath, et la présentation est enregistrée au format PPTX.
import com.aspose.slides.*;
import android.graphics.PointF;
float shapeX = 20f;
float shapeY = 20f;
float shapeWidth = 300f;
float shapeHeight = 200f;
float leftTopSize = 50f;
float rightTopSize = 20f;
float rightBottomSize = 40f;
float leftBottomSize = 10f;
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape shape = slide.getShapes().addAutoShape(ShapeType.Custom, shapeX, shapeY, shapeWidth, shapeHeight);
PointF topLeft = new PointF(leftTopSize, 0);
PointF topRight = new PointF(shapeWidth - rightTopSize, 0);
PointF rightBottom = new PointF(shapeWidth, shapeHeight - rightBottomSize);
PointF bottomLeft = new PointF(leftBottomSize, shapeHeight);
PointF leftTop = new PointF(0, leftTopSize);
GeometryPath geometryPath = new GeometryPath();
geometryPath.moveTo(topLeft);
geometryPath.lineTo(topRight);
geometryPath.arcTo(rightTopSize, rightTopSize, 180, -90);
geometryPath.lineTo(rightBottom);
geometryPath.arcTo(rightBottomSize, rightBottomSize, -90, -90);
geometryPath.lineTo(bottomLeft);
geometryPath.arcTo(leftBottomSize, leftBottomSize, 0, -90);
geometryPath.lineTo(leftTop);
geometryPath.arcTo(leftTopSize, leftTopSize, 90, -90);
geometryPath.closeFigure();
shape.setGeometryPath(geometryPath);
presentation.save("output.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Déterminer si la géométrie d’une forme est fermée
L’assistant suivant vérifie si chaque chemin de géométrie non vide se termine par un segment de fermeture. Il lit IGeometryPath.getPathData et compare la IPathSegment.getPathCommand du segment final avec PathCommandType.Close. Il renvoie false lorsqu’il n’existe aucun chemin non vide. Cette vérification porte sur la commande finale de chaque chemin ; elle n’inspecte pas chaque sous‑figure d’un chemin. L’exemple affiche true pour un rectangle.
import com.aspose.slides.*;
class GeometryInspector {
boolean isGeometryClosed(IGeometryShape geometryShape) {
boolean hasNonemptyPath = false;
for (IGeometryPath geometryPath : geometryShape.getGeometryPaths()) {
IPathSegment[] segments = geometryPath.getPathData();
if (segments.length == 0) {
continue;
}
hasNonemptyPath = true;
IPathSegment lastSegment = segments[segments.length - 1];
if (lastSegment.getPathCommand() != PathCommandType.Close) {
return false;
}
}
return hasNonemptyPath;
}
}
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 100, 100, 200, 100);
GeometryInspector inspector = new GeometryInspector();
boolean closed = inspector.isGeometryClosed(shape);
System.out.println(closed);
} finally {
presentation.dispose();
}
Extraire et inspecter les éléments de forme
Utilisez IGeometryShape.createShapeElements pour inspecter une forme existante en tant qu’éléments contenant des points de chemin et des types de points. Convertissez chaque IShapeElement retourné en ShapeElement afin de récupérer les tableaux de points et de types via les méthodes getPathPoints et getPathTypes . Cette représentation est utile pour l’analyse de contour ou pour transmettre la géométrie à des outils de dessin personnalisés.
L’exemple ouvre input.pptx, trouve la première forme de géométrie directement sur la première diapositive et affiche ses segments de chemin. Utilisez une présentation contenant une forme avec des segments droits et courbes pour voir les deux types de sorties. Il ne recherche pas à l’intérieur des groupes.
import com.aspose.slides.*;
import android.graphics.PointF;
Presentation presentation = new Presentation("input.pptx");
try {
ISlide slide = presentation.getSlides().get_Item(0);
IGeometryShape shape = null;
for (IShape candidate : slide.getShapes()) {
if (candidate instanceof IGeometryShape) {
shape = (IGe GeometryShape) candidate;
break;
}
}
if (shape == null) {
System.out.println("No geometry shape found on the first slide.");
} else {
for (IShapeElement element : shape.createShapeElements()) {
ShapeElement shapeElement = (ShapeElement) element;
PointF[] points = shapeElement.getPathPoints();
byte[] types = shapeElement.getPathTypes();
System.out.println("Shape element:");
for (int i = 0; i < points.length; i++) {
int pointType = types[i] & 0x07; // Conserver le type de segment, en excluant les drapeaux.
switch (pointType) {
case 0:
System.out.println("Start figure at " + points[i]);
break;
case 1:
System.out.println("Line to " + points[i]);
break;
case 3:
System.out.println("Cubic Bezier: controls " + points[i] + ", " + points[i + 1] + "; end " + points[i + 2]);
i += 2; // Consommer les deux points de contrôle et le point final.
break;
}
if ((types[i] & 0x80) != 0) {
System.out.println("Close subpath back to its starting point.");
}
}
}
}
} finally {
presentation.dispose();
}
Les tableaux correspondent par indice : points[i] est un point et types[i] décrit son rôle. Le type 0 démarre une figure, et le type 1 trace une ligne du point précédent au point actuel. Un segment de Bézier cubique commence au point final précédent et utilise trois entrées de type 3 consécutives : deux points de contrôle suivis du nouveau point final. La boucle consomme ces trois entrées ensemble et vérifie le point final pour la fermeture.
Les types de point contiennent également des drapeaux. Masquez avec 0x07 pour identifier le type de segment, et testez 0x80 séparément pour détecter un sous‑chemin fermé. Par exemple, 129 (0x81) signifie un point final de ligne qui ferme un sous‑chemin, et 131 (0x83) signifie un point final de Bézier qui en ferme un. Java stocke ces drapeaux dans des octets signés ; le masquage préserve les valeurs de bits souhaitées. Comparer la valeur brute uniquement à 1 ou 3 manquerait ces cas. D’autres drapeaux, tels que le tiret (0x10) et le marqueur (0x20), ne changent pas le type de segment de base.
Coordonnées et transformations. Les points sont mesurés en points (1/72 pouce), X augmentant vers la droite et Y augmentant vers le bas. Pour une forme non groupée, les coordonnées extraites incluent déjà la position renvoyée par getX et getY et reflètent sa largeur et hauteur actuelles. Par exemple, un rectangle non tourné à (100, 200) avec une taille de 120 × 80 possède des limites de contour (100, 200)–(220, 280). N’ajoutez pas de nouveau la position de la forme. Soustrayez son X et Y pour obtenir des coordonnées relatives à son cadre non tourné.
Les points extraits n’appliquent pas la rotation de la forme, renvoyée par getRotation, ni les retournements horizontaux et verticaux. Pour reproduire le contour affiché, appliquez ces transformations autour du centre de la forme. Pour les formes groupées, tenez également compte du mappage des coordonnées du groupe et des transformations ; ne supposez pas que les points extraits sont les coordonnées finales rendues sur la diapositive ou appliquez une translation ou une échelle deux fois s’ils sont déjà reflétés dans le cadre de l’enfant.
Inspection versus édition. Les tableaux extraits décrivent le contour ; les modifier ne met pas à jour la forme d’origine. Choisissez cette approche lorsque votre code d’analyse ou de dessin nécessite des tableaux de points/types. Utilisez getGeometryPaths lorsque vous avez besoin des commandes de géométrie dans le système de coordonnées local de la forme ou que vous souhaitez éditer sa géométrie. Appliquez les chemins modifiés via setGeometryPath ou setGeometryPaths.
FAQ
Que se passe-t-il avec le remplissage et le contour après le remplacement de la géométrie ?
Le style reste attaché à la forme ; seul le contour change. Le remplissage et le contour sont appliqués automatiquement à la nouvelle géométrie.
Comment faire pivoter correctement une forme personnalisée avec sa géométrie ?
Utilisez la méthode setRotation de la forme ; la géométrie pivote avec la forme car elle est liée au système de coordonnées propre à la forme.
Puis‑je convertir une forme personnalisée en image pour « verrouiller » le résultat ?
Oui. Exportez la zone de la diapositive requise ou la forme elle‑même vers un format raster ; cela simplifie le travail ultérieur avec des géométries complexes.