Anpassa presentationsformer i PHP
Översikt
Den här artikeln förklarar hur du anpassar presentationsformer i Aspose.Slides genom att redigera formgeometri via redigeringspunkter och geometriska banor. Den visar hur du arbetar med GeometryPath för att ändra befintliga former, utföra grundläggande redigeringsoperationer för banor, lägga till eller ta bort punkter och applicera uppdaterad geometri tillbaka 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, inspekterar formelement och konverterar Java AWT-textkonturer till geometriska banor.
Ä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 kurvaturen på en punkt.
- Lägg till nya punkter.
Att redigera punkter låter dig ä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, håll dessa koncept i åtanke:
- En form (eller dess bana) kan antingen vara sluten eller öppen.
- En forms bana består av ankarpunkter som är sammanlänkade av segment.
- Ett segment kan vara rakt eller kurvat. Ankaspunkter och kontrollhandtag bestämmer dess form.
- Ankare finns som hörnpunkter, raka punkter eller mjuka punkter:
- Vid en hörnpunkt kan intilliggande segment mötas i en vinkel.
- Vid en mjuk punkt är de två kontrollhandtagen i linje och lika långt från ankaret.
- Vid en rak punkt är de två kontrollhandtagen i linje men kan ha olika avstånd från ankaret.
- Att flytta ankarpunkter eller justera deras handtag förändrar formens kontur.
För att redigera PowerPoint‑former via redigeringspunkter tillhandahåller Aspose.Slides klassen GeometryPath.
- En GeometryPath‑instans representerar en geometrisk bana för objektet GeometryShape.
- För att hämta GeometryPath från GeometryShape-instansen kan du använda metoden GeometryShape::getGeometryPaths.
- För att ange GeometryPath för en form kan du använda dessa metoder: GeometryShape::setGeometryPath för former med en enda bana och GeometryShape::setGeometryPaths för former med flera banor.
- För att lägga till segment kan du använda metoderna under GeometryPath.
- Genom att använda metoderna GeometryPath::setStroke och GeometryPath::setFillMode kan du ange utseendet för en geometrisk bana.
- Genom att använda metoden GeometryPath::getPathData kan du hämta geometrisk bana för en GeometryShape som en array av bansegment.
- För att komma åt ytterligare anpassningsalternativ för formgeometri kan du läsa en java.awt.Shape via dess PathIterator och spela upp segmenten på en GeometryPath.
Enkla redigeringsoperationer
Använd följande metoder för att redigera en geometrisk bana. Överlagringar som accepterar ett index infogar ett segment på den nollbaserade positionen i banans segmentarray.
| 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 de angivna dimensionerna och vinklarna i grader. | GeometryPath::arcTo |
| Stäng den aktuella figur genom att ansluta dess slutpunkt till dess startpunkt. | GeometryPath::closeFigure |
| Ange startpunkten för en figur. | GeometryPath::moveTo |
| Ta bort ett segment på en nollbaserad indexposition. | GeometryPath::removeAt |
Lägg till anpassade punkter till en form
Detta exempel infogar två punkter i en rektangulär form med hjälp av GeometryPath::lineTo och applicerar den redigerade banan med GeometryShape::setGeometryPath. Koordinaterna är lokala för formen: båda nya punkterna är 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.
use aspose\slides\Presentation;
use aspose\slides\ShapeType;
$presentation = new Presentation();
try {
$slide = $presentation->getSlides()->get_Item(0);
$shape = $slide->getShapes()->addAutoShape(ShapeType::Rectangle, 100, 100, 200, 100);
$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. Att applicera den modifierade banan med GeometryShape::setGeometryPath uppdaterar formens kontur.
use aspose\slides\Presentation;
use aspose\slides\ShapeType;
$presentation = new Presentation();
try {
$slide = $presentation->getSlides()->get_Item(0);
$shape = $slide->getShapes()->addAutoShape(ShapeType::Heart, 100, 100, 300, 300);
$path = $shape->getGeometryPaths()[0];
$path->removeAt(2);
$shape->setGeometryPath($path);
} finally {
$presentation->dispose();
}

Skapa en anpassad form
Detta exempel bygger en femtackig stjärna med GeometryPath. Alternerande yttre och inre radier på 100 respektive 50 punkter definierar spetsarna och inbuktningarna; ett steg på 72 grader placerar de fem spetsarna jämnt. Banan stängs med GeometryPath::closeFigure och appliceras på en rektangulär form med GeometryShape::setGeometryPath, vilket ersätter dess kontur.
use aspose\slides\GeometryPath;
use aspose\slides\Presentation;
use aspose\slides\ShapeType;
$points = [];
$outerRadius = 100;
$innerRadius = 50;
$angleStep = 72;
for ($angle = -90; $angle < 270; $angle += $angleStep) {
$radians = deg2rad($angle);
$points[] = [$outerRadius * cos($radians) + $outerRadius, $outerRadius * sin($radians) + $outerRadius];
$radians = deg2rad($angle + $angleStep / 2);
$points[] = [$innerRadius * cos($radians) + $outerRadius, $innerRadius * sin($radians) + $outerRadius];
}
$starPath = new GeometryPath();
$starPath->moveTo($points[0][0], $points[0][1]);
for ($i = 1; $i < count($points); $i++) {
$starPath->lineTo($points[$i][0], $points[$i][1]);
}
$starPath->closeFigure();
$presentation = new Presentation();
try {
$slide = $presentation->getSlides()->get_Item(0);
$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å slutna GeometryPath‑objekt för den övre och nedre tredjedelen av en form. Genom att applicera båda banorna med GeometryShape::setGeometryPaths skapas en enda sammansatt form med ett glapp över dess mitttredjedel.
use aspose\slides\GeometryPath;
use aspose\slides\Presentation;
use aspose\slides\ShapeType;
$presentation = new Presentation();
try {
$slide = $presentation->getSlides()->get_Item(0);
$shape = $slide->getShapes()->addAutoShape(ShapeType::Rectangle, 100, 100, 200, 100);
$topPath = new GeometryPath();
$topPath->moveTo(0, 0);
$topPath->lineTo(java_values($shape->getWidth()), 0);
$topPath->lineTo(java_values($shape->getWidth()), java_values($shape->getHeight()) / 3);
$topPath->lineTo(0, java_values($shape->getHeight()) / 3);
$topPath->closeFigure();
$bottomPath = new GeometryPath();
$bottomPath->moveTo(0, java_values($shape->getHeight()) / 3 * 2);
$bottomPath->lineTo(java_values($shape->getWidth()), java_values($shape->getHeight()) / 3 * 2);
$bottomPath->lineTo(java_values($shape->getWidth()), java_values($shape->getHeight()));
$bottomPath->lineTo(0, java_values($shape->getHeight()));
$bottomPath->closeFigure();
$shape->setGeometryPaths([$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åtvända böjda hörn. Varje hörnstorlek anger bågens bredd och höjd i punkter, och den -90‑gradiga svepningen ritar en moturs kvartselipse. Den färdiga banan appliceras med GeometryShape::setGeometryPath, och presentationen sparas i PPTX‑format.
use aspose\slides\GeometryPath;
use aspose\slides\Point2DFloat;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;
use aspose\slides\ShapeType;
$shapeX = 20;
$shapeY = 20;
$shapeWidth = 300;
$shapeHeight = 200;
$leftTopSize = 50;
$rightTopSize = 20;
$rightBottomSize = 40;
$leftBottomSize = 10;
$presentation = new Presentation();
try {
$slide = $presentation->getSlides()->get_Item(0);
$shape = $slide->getShapes()->addAutoShape(ShapeType::Custom, $shapeX, $shapeY, $shapeWidth, $shapeHeight);
$topLeft = new Point2DFloat($leftTopSize, 0);
$topRight = new Point2DFloat($shapeWidth - $rightTopSize, 0);
$rightBottom = new Point2DFloat($shapeWidth, $shapeHeight - $rightBottomSize);
$bottomLeft = new Point2DFloat($leftBottomSize, $shapeHeight);
$leftTop = new Point2DFloat(0, $leftTopSize);
$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 geometrisk bana avslutas med ett stängningssegment. Den läser GeometryPath::getPathData och jämför det sista segmentets PathSegment::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 underfigur i en bana. Exemplet skriver ut true för en rektangel.
use aspose\slides\PathCommandType;
use aspose\slides\Presentation;
use aspose\slides\ShapeType;
function isGeometryClosed($geometryShape)
{
$hasNonemptyPath = false;
foreach ($geometryShape->getGeometryPaths() as $geometryPath) {
$segments = java_values($geometryPath->getPathData());
if (count($segments) === 0) {
continue;
}
$hasNonemptyPath = true;
$lastSegment = $segments[count($segments) - 1];
if (java_values($lastSegment->getPathCommand()) !== PathCommandType::Close) {
return false;
}
}
return $hasNonemptyPath;
}
$presentation = new Presentation();
try {
$slide = $presentation->getSlides()->get_Item(0);
$shape = $slide->getShapes()->addAutoShape(ShapeType::Rectangle, 100, 100, 200, 100);
$closed = isGeometryClosed($shape);
echo ($closed ? "true" : "false") . PHP_EOL;
} finally {
$presentation->dispose();
}
Extrahera och inspektera formelement
Använd GeometryShape::createShapeElements för att inspektera en befintlig form som element som innehåller banpunkter och punktstyper. Använd varje returnerad ShapeElement för att hämta punkt- och typarrayerna via metoderna getPathPoints och getPathTypes. Denna representation är användbar för kontur‑analys eller för att vidarebefordra geometri till anpassade ritverktyg.
Exemplet öppnar input.pptx, hittar den första geometriska formen direkt på den första bilden och skriver ut dess bansegment. Använd en presentation som innehåller en form med raka och böjda segment för att se båda typerna av utslag. Det söker inte inne i grupper.
use aspose\slides\Presentation;
$presentation = new Presentation("input.pptx");
try {
$slide = $presentation->getSlides()->get_Item(0);
$shape = null;
$shapes = $slide->getShapes();
for ($shapeIndex = 0; $shapeIndex < java_values($shapes->size()); $shapeIndex++) {
$candidate = $shapes->get_Item($shapeIndex);
if (java_instanceof($candidate, java("com.aspose.slides.GeometryShape"))) {
$shape = $candidate;
break;
}
}
if ($shape === null) {
echo "No geometry shape found on the first slide." . PHP_EOL;
} else {
foreach ($shape->createShapeElements() as $element) {
$points = java_values($element->getPathPoints());
$types = array_values(unpack("C*", java_values($element->getPathTypes())));
echo "Shape element:" . PHP_EOL;
for ($i = 0; $i < count($points); $i++) {
$pointType = $types[$i] & 0x07; // Behåll segmenttypen, exklusive flaggor.
switch ($pointType) {
case 0:
echo "Start figure at " . $points[$i] . PHP_EOL;
break;
case 1:
echo "Line to " . $points[$i] . PHP_EOL;
break;
case 3:
echo "Cubic Bezier: controls " . $points[$i] . ", " . $points[$i + 1] . "; end " . $points[$i + 2] . PHP_EOL;
$i += 2; // Förbrukar båda kontrollpunkterna och slutpunkten.
break;
}
if (($types[$i] & 0x80) !== 0) {
echo "Close subpath back to its starting point." . PHP_EOL;
}
}
}
}
} finally {
$presentation->dispose();
}
Arrayerna motsvarar varandra genom 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 förbrukar dessa tre poster tillsammans och kontrollerar slutpunkten för slutenhet.
Punkttyper innehåller också flaggor. Maskera med 0x07 för att identifiera segmenttypen och testa 0x80 separat för att upptäcka ett stängt underbana. Till exempel betyder 129 (0x81) en linjeslutpunkt som stänger en underbana, och 131 (0x83) betyder en Bézier‑slutpunkt som stänger en sådan. PHP/Java‑bron returnerar byte‑arrayen som en binär sträng; att packa upp den med “C*” ger osignerade byte‑värden. Maskering bevarar de avsedda bitvärdena. Att bara jämföra råvärdet med 1 eller 3 skulle missa dessa fall. Andra flaggor, såsom streck (0x10) och markör (0x20), förändrar inte bassegmenttypen.
Koordinater och transformationer. Punkter mäts i punkter (1/72 tum), med X ökande åt höger och Y ökande nedåt. För en opåverkad form inkluderar de extraherade koordinaterna redan positionen som returneras av getX och getY och återspeglar dess aktuella bredd och höjd. Till exempel har en icke‑roterad rektangel vid (100, 200) med storlek 120 × 80 konturgränser (100, 200)–(220, 280). Lägg inte till formens position igen. Subtrahera dess X och Y för att få koordinater relativt till dess icke‑roterade ram.
De extraherade punkterna tillämpar inte formens rotation, som returneras av getRotation, eller horisontella och vertikala speglingar. För att återge den visade konturen, applicera dessa transformationer kring formens centrum. För grupperade former, ta även hänsyn till gruppens koordinat‑mappning och transformationer; förutsätt inte att de extraherade punkterna är de slutgiltiga renderade bild‑koordinaterna eller applicera en förflyttning eller skala två gånger om den redan återspeglas i barnets ram.
Inspektion kontra redigering. Extraherade arrayer beskriver konturen; att ändra dem uppdaterar inte originalformen. 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 geometriska kommandon i formens lokala koordinatsystem eller vill redigera dess geometri. Applicera redigerade banor via setGeometryPath eller setGeometryPaths.
Konvertera en Java AWT-form till GeometryPath
Detta exempel kombinerar en rektangulär kontur med text som konverterats till geometri. Konturens setFillMode-metod inaktiverar dess fyllning. En GlyphVector skapar textkonturen i en java.awt.Shape. Dess PathIterator levererar flytt‑, linje‑, kvadratisk‑, kubisk‑ och stängningssegment, vilka exemplet spelar upp på en GeometryPath.
Exemplet använder en Java‑float‑array så att PHP/Java‑bron behåller koordinaterna som skrivits av iteratorn. Texten använder en 40‑punkts Arial‑font. Konturen är förskjuten 20 punkter horisontellt och placerad så att dess visuella topp är 10 punkter under formens överkant. Textbanan är fylld, medan den ursprungliga rektangeln förblir en kontur. Att applicera båda banorna med GeometryShape::setGeometryPaths ger en enda form som innehåller rektangeln och texten.
use aspose\slides\GeometryPath;
use aspose\slides\PathFillModeType;
use aspose\slides\Presentation;
use aspose\slides\ShapeType;
$presentation = new Presentation();
try {
$slide = $presentation->getSlides()->get_Item(0);
$shape = $slide->getShapes()->addAutoShape(ShapeType::Rectangle, 100, 100, 300, 100);
$originalPath = $shape->getGeometryPaths()[0];
$originalPath->setFillMode(PathFillModeType::None);
$fontClass = java("java.awt.Font");
$imageClass = java("java.awt.image.BufferedImage");
$font = new Java("java.awt.Font", "Arial", $fontClass->PLAIN, 40);
$image = new Java("java.awt.image.BufferedImage", 100, 100, $imageClass->TYPE_INT_ARGB);
$graphics = $image->createGraphics();
try {
$fontContext = $graphics->getFontRenderContext();
$glyphVector = $font->createGlyphVector($fontContext, "Text in shape");
$textBounds = $glyphVector->getVisualBounds();
$baseline = -java_values($textBounds->getY()) + 10;
$graphicsPath = $glyphVector->getOutline(20.0, $baseline);
} finally {
$graphics->dispose();
}
$textPath = new GeometryPath();
$pathIterator = $graphicsPath->getPathIterator(null);
$iteratorClass = java("java.awt.geom.PathIterator");
$arrayClass = java("java.lang.reflect.Array");
$floatClass = java("java.lang.Float");
$coordinates = $arrayClass->newInstance($floatClass->TYPE, 6);
while (!java_values($pathIterator->isDone())) {
$segmentType = java_values($pathIterator->currentSegment($coordinates));
$points = java_values($coordinates);
switch ($segmentType) {
case java_values($iteratorClass->SEG_MOVETO):
$textPath->moveTo($points[0], $points[1]);
break;
case java_values($iteratorClass->SEG_LINETO):
$textPath->lineTo($points[0], $points[1]);
break;
case java_values($iteratorClass->SEG_QUADTO):
$textPath->quadraticBezierTo($points[0], $points[1], $points[2], $points[3]);
break;
case java_values($iteratorClass->SEG_CUBICTO):
$textPath->cubicBezierTo($points[0], $points[1], $points[2], $points[3], $points[4], $points[5]);
break;
case java_values($iteratorClass->SEG_CLOSE):
$textPath->closeFigure();
break;
}
$pathIterator->next();
}
$textPath->setFillMode(PathFillModeType::Normal);
$shape->setGeometryPaths([$originalPath, $textPath]);
} finally {
$presentation->dispose();
}

Vanliga frågor
Vad händer med fyllning och kontur efter att geometrin ersatts?
Stilen förblir på formen; endast konturen ä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 roteras 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 nödvändiga slide‑området eller själva shape till ett rasterformat; detta förenklar vidare arbete med komplexa geometrier.