Anpassa presentationsformer på Android
Översikt
Denna artikel förklarar hur du anpassar presentationsformer i Aspose.Slides genom att redigera formgeometri via redigeringspunkter och geometrivägar. Den visar hur du arbetar med GeometryPath och IGeometryPath för att ändra befintliga former, utföra grundläggande redigeringsoperationer för vägar, lägga till eller ta bort punkter och tillämpa den uppdaterade geometrin på en form.
Den visar också hur du skapar anpassade och sammansatta former, bygger former med rundade hörn, avgör om en formgeometri är sluten och inspekterar formelement med Android‑punktarrayer.
Ändra en form med redigeringspunkter
I PowerPoint kan du använda Edit Points för att ändra en fyrkant:
- Flytta ett hörn inåt eller utåt.
- Justera krökningen vid en punkt.
- Lägg till nya punkter.
Genom att redigera punkter kan du ändra en forms kontur eller använda en befintlig form som grund för en ny.
Tips för formredigering

När du redigerar PowerPoint‑former, ha dessa koncept i åtanke:
- En form (eller dess bana) kan antingen vara sluten eller öppen.
- En forms bana består av ankarpunkter som är sammankopplade av segment.
- Ett segment kan vara rakt eller kurvat. Ankarlägen och kontrollhandtag bestämmer dess form.
- Ankarlägen finns som hörnpunkter, raka punkter eller släta punkter:
- Vid en hörnpunkt kan intilliggande segment mötas i en vinkel.
- Vid en slät punkt är de två kontrollhandtagen i linje och lika långt från ankarläget.
- Vid en rak punkt är de två kontrollhandtagen i linje men kan ha olika avstånd från ankarläget.
- Att flytta ankarlägen eller justera deras handtag ändrar formens kontur.
För att redigera PowerPoint‑former via redigeringspunkter tillhandahåller Aspose.Slides klassen GeometryPath och gränssnittet IGeometryPath.
- En GeometryPath‑instans representerar en geometribana för objektet IGeometryShape.
- För att hämta GeometryPath från IGeometryShape‑instansen kan du använda metoden IGeometryShape.getGeometryPaths .
- För att ange GeometryPath för en form kan du använda dessa metoder: IGeometryShape.setGeometryPath för former med en enda bana och IGeometryShape.setGeometryPaths för former med flera banor.
- För att lägga till segment kan du använda metoderna under IGeometryPath.
- Genom att använda metoderna IGeometryPath.setStroke och IGeometryPath.setFillMode kan du ange utseendet för en geometribana.
- Genom att använda metoden IGeometryPath.getPathData kan du hämta geometribanan för en GeometryShape som en array av segment.
Enkla redigeringsoperationer
Använd följande metoder för att redigera en geometribana. Överlagringar som tar ett index sätter in ett segment på den nollbaserade positionen i banasegment‑arrayen.
| Operation | Metod |
|---|---|
| Lägg till eller infoga en rak linje. | GeometryPath.lineTo |
| Lägg till eller infoga en kubisk Bézier‑kurva med två kontrollpunkter och en slutpunkt. | GeometryPath.cubicBezierTo |
| Lägg till eller infoga en kvadratisk Bézier‑kurva med en kontrollpunkt och en slutpunkt. | GeometryPath.quadraticBezierTo |
| Lägg till en elliptisk båge med angivna dimensioner och vinklar i grader. | GeometryPath.arcTo |
| Stäng den aktuella figur genom att koppla dess slutpunkt till dess startpunkt. | GeometryPath.closeFigure |
| Ange startpunkten för en figur. | GeometryPath.moveTo |
| Ta bort ett segment på en nollbaserad index. | GeometryPath.removeAt |
Lägg till anpassade punkter i en form
Detta exempel infogar två punkter i en rektangulär form med GeometryPath.lineTo och tillämpar den redigerade banan med IGeometryShape.setGeometryPath. Koordinaterna är lokala för formen: båda nya punkterna ligger i dess centrum, 100 punkter från vänster och 50 punkter från toppen. Segmentindex 1 och 4 placerar dem på de övre och nedre kanterna och drar dessa kanter inåt.
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();
}

Ta bort punkter från en form
Detta exempel ändrar en hjärtformad kontur genom att ta bort segmentet på nollbaserad index 2 med GeometryPath.removeAt. Genom att tillämpa den modifierade banan med IGeometryShape.setGeometryPath uppdateras formens kontur.
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();
}

Skapa en anpassad form
Detta exempel bygger en femspetsig stjärna med GeometryPath. Växlande yttre och inre radier på 100 respektive 50 punkter definierar spetsarna och indragningarna; ett 72‑gradigt steg placerar de fem spetsarna jämnt. Banam avslutas med GeometryPath.closeFigure och appliceras på en rektangulär form med IGeometryShape.setGeometryPath, vilket ersätter dess kontur.
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();
}

Skapa en sammansatt anpassad form
Detta exempel definierar två sluta GeometryPath‑objekt för de övre och nedre tredjedelarna av en form. Genom att tillämpa båda banorna med IGeometryShape.setGeometryPaths skapas en enda sammansatt form med ett glapp över dess mittersta tredjedel.
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();
}

Skapa en anpassad form med rundade hörn
Detta exempel kombinerar raka segment med GeometryPath.arcTo för att skapa en form med inåtkurvade hörn. Varje hörnstorlek anger bågens bredd och höjd i punkter, och den -90‑gradiga svepningen ritar en moturs kvartselips. Den färdiga banan appliceras med IGeometryShape.setGeometryPath, och presentationen sparas i PPTX‑format.
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();
}
Ta reda på om en formgeometri är sluten
Följande hjälpfunktion kontrollerar om varje icke‑tom geometribana avslutas med ett slutsegment. Den läser IGeometryPath.getPathData och jämför det sista segmentets IPathSegment.getPathCommand med PathCommandType.Close. Den returnerar false när det inte finns några icke‑tomma banor. Detta kontrollerar det sista kommandet för varje bana; den inspekterar inte varje subfigur inom en bana. Exemplet skriver ut true för en rektangel.
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();
}
Extrahera och inspektera formelement
Använd IGeometryShape.createShapeElements för att inspektera en befintlig form som element som innehåller banapunkter och punttyper. Kast varje returnerad IShapeElement till ShapeElement för att hämta punkt‑ och typ‑arrayerna via metoderna getPathPoints och getPathTypes . Denna representation är användbar för kontur‑analys eller för att skicka geometri till anpassade ritverktyg.
Exemplet öppnar input.pptx, hittar den första geometri‑formen direkt på den första bilden och skriver ut dess bansegment. Använd en presentation som innehåller en form med raka och kurviga segment för att se båda typerna av utskrift. Det söker inte i grupper.
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 = (IGeometryShape) 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; // Behåll segmenttypen, exklusive flaggor.
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; // Consume both control points and the endpoint.
break;
}
if ((types[i] & 0x80) != 0) {
System.out.println("Close subpath back to its starting point.");
}
}
}
}
} finally {
presentation.dispose();
}
Arrayerna korresponderar efter index: points[i] är en punkt och types[i] beskriver dess roll. Typ 0 startar en figur, och typ 1 ritar en linje från föregående punkt till den aktuella. Ett kubiskt Bézier‑segment startar vid föregående slutpunkt och använder tre på varandra följande typ‑3‑poster: två kontrollpunkter följda av den nya slutpunkten. Loopen konsumerar dessa tre poster tillsammans och kontrollerar om slutpunkten är sluten.
Punkt‑typer innehåller också flaggor. Maskera med 0x07 för att identifiera segmenttypen och testa 0x80 separat för att upptäcka en sluten delbana. Till exempel betyder 129 (0x81) en linjeslutpunkt som stänger en delbana, och 131 (0x83) betyder en Bézier‑slutpunkt som stänger en. Java lagrar dessa flaggor i signerade byte; maskering bevarar de avsedda bitvärdena. Att bara jämföra det råa värdet med 1 eller 3 skulle missa dessa fall. Andra flaggor, såsom streck (0x10) och markör (0x20), ändrar inte bassegmenttypen.
Koordinater och transformationer. Punkter mäts i punkter (1/72 tum), med X som ökar åt höger och Y som ökar nedåt. För en ogrupperad form inkluderar de extraherade koordinaterna redan positionen som returneras av getX och getY och reflekterar dess nuvarande bredd och höjd. Till exempel har en orotated rektangel på (100, 200) med storlek 120 × 80 konturbounderna (100, 200)–(220, 280). Lägg inte till formens position igen. Subtrahera dess X och Y för att få koordinater relativt till dess orotated ram.
De extraherade punkterna applicerar inte formens rotation, som returneras av getRotation, eller horisontella och vertikala speglingar. För att reproducera den visade konturen, applicera dessa transformationer runt formens centrum. För grupperade former, ta även hänsyn till gruppens koordinat‑mappning och transformationer; anta inte att de extraherade punkterna är de slutgiltiga renderade bild‑koordinaterna eller applicera en translation eller skala två gånger om den redan reflekteras i barnets ram.
Inspektion kontra redigering. Extraherade arrayer beskriver konturen; att förändra dem uppdaterar inte den ursprungliga formen. Välj detta tillvägagångssätt när din analys‑ eller ritkod behöver punkt‑/typ‑arrayer. Använd getGeometryPaths när du behöver geometrikommando i formens lokala koordinatsystem eller vill redigera dess geometri. Applicera redigerade banor via setGeometryPath eller setGeometryPaths.
FAQ
Vad händer med fyllning och kontur efter att geometrin har ersatts?
Stilen förblir på formen; endast konturen förändras. Fyllning och kontur appliceras automatiskt på den nya geometrin.
Hur roterar jag en anpassad form korrekt tillsammans med dess geometri?
Använd formens setRotation‑metod; geometrin roterar med formen eftersom den är bunden till formens eget koordinatsystem.
Kan jag konvertera en anpassad form till en bild för att “låsa” resultatet?
Ja. Exportera det önskade bildspel‑området eller själva form till ett rasterformat; detta förenklar vidare arbete med komplexa geometrier.