Dostosuj kształty prezentacji na Androidzie
Przegląd
Ten artykuł wyjaśnia, jak dostosować kształty prezentacji w Aspose.Slides poprzez edycję geometrii kształtu za pomocą punktów edycji i ścieżek geometrycznych. Pokazuje, jak pracować z GeometryPath i IGeometryPath w celu modyfikacji istniejących kształtów, wykonywania podstawowych operacji edycji ścieżek, dodawania lub usuwania punktów oraz zastosowania zaktualizowanej geometrii z powrotem do kształtu.
Demonstruje również, jak tworzyć własne i złożone kształty, budować kształty z zaokrąglonymi narożnikami, określać, czy geometria kształtu jest zamknięta, oraz przeglądać elementy kształtu przy użyciu tablic punktów Android.
Zmiana kształtu za pomocą punktów edycji
W PowerPoint możesz używać Punktów edycji, aby modyfikować kwadrat:
- Przesuwać narożnik do wewnątrz lub na zewnątrz.
- Dostosowywać krzywiznę w danym punkcie.
- Dodawać nowe punkty.
Edycja punktów pozwala zmienić kontur kształtu lub użyć istniejącego kształtu jako podstawy dla nowego.
Wskazówki dotyczące edycji kształtów

Podczas edycji kształtów w PowerPoint pamiętaj o następujących pojęciach:
- Kształt (lub jego ścieżka) może być zamknięty lub otwarty.
- Ścieżka kształtu składa się z punktów kotwicowych połączonych odcinkami.
- Odcinek może być prosty lub krzywy. Kształt określają punkty kotwicowe i uchwyty kontrolne.
- Punkty kotwicowe występują jako punkty narożne, proste lub gładkie:
- W punkcie narożnym łączące się odcinki mogą tworzyć kąt.
- W punkcie gładkim dwa uchwyty kontrolne są wyrównane i znajdują się w jednakowej odległości od punktu kotwicowego.
- W punkcie prostym dwa uchwyty kontrolne są wyrównane, ale mogą mieć różne odległości od punktu kotwicowego.
- Przesuwanie punktów kotwicowych lub regulacja ich uchwytów zmienia obrys kształtu.
Aby edytować kształty PowerPoint za pomocą punktów edycji, Aspose.Slides udostępnia klasę GeometryPath oraz interfejs IGeometryPath.
- Instancja GeometryPath reprezentuje ścieżkę geometryczną obiektu IGeometryShape.
- Aby pobrać GeometryPath z instancji IGeometryShape, można użyć metody IGeometryShape.getGeometryPaths.
- Aby ustawić GeometryPath dla kształtu, można użyć metod: IGeometryShape.setGeometryPath dla kształtów z jedną ścieżką oraz IGeometryShape.setGeometryPaths dla kształtów z wieloma ścieżkami.
- Aby dodać odcinki, można używać metod dostępnych w IGeometryPath.
- Korzystając z metod IGeometryPath.setStroke i IGeometryPath.setFillMode, można określić wygląd ścieżki geometrycznej.
- Metodą IGeometryPath.getPathData można pobrać ścieżkę geometryczną obiektu GeometryShape jako tablicę segmentów ścieżki.
Proste operacje edycji
Użyj poniższych metod, aby edytować ścieżkę geometryczną. Przeciążenia przyjmujące indeks wstawiają odcinek w podanej, zerowo‑indeksowanej pozycji w tablicy odcinków ścieżki.
| Operacja | Metoda |
|---|---|
| Dodaj lub wstaw prostą linię. | GeometryPath.lineTo |
| Dodaj lub wstaw krzywą Béziera trzeciego stopnia z dwoma punktami kontrolnymi i punktem końcowym. | GeometryPath.cubicBezierTo |
| Dodaj lub wstaw krzywą Béziera drugiego stopnia z jednym punktem kontrolnym i punktem końcowym. | GeometryPath.quadraticBezierTo |
| Dodaj łuk eliptyczny o podanych wymiarach i kątach w stopniach. | GeometryPath.arcTo |
| Zamknij bieżącą figurę, łącząc jej punkt końcowy z punktem początkowym. | GeometryPath.closeFigure |
| Ustaw punkt początkowy figury. | GeometryPath.moveTo |
| Usuń odcinek o podanym zerowo‑indeksowanym indeksie. | GeometryPath.removeAt |
Dodawanie własnych punktów do kształtu
Poniższy przykład wstawia dwa punkty do prostokątnego kształtu przy użyciu GeometryPath.lineTo i stosuje edytowaną ścieżkę za pomocą IGeometryShape.setGeometryPath. Współrzędne są lokalne względem kształtu: oba nowe punkty znajdują się w jego środku, 100 punktów od lewej i 50 punktów od góry. Indeksy segmentów 1 i 4 umieszczają je na górnej i dolnej krawędzi, ściągając te krawędzie do środka.
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();
}

Usuwanie punktów z kształtu
Przykład modyfikuje obrys serca, usuwając segment o zerowo‑indeksowanym indeksie 2 przy użyciu GeometryPath.removeAt. Zastosowanie zmodyfikowanej ścieżki za pomocą IGeometryShape.setGeometryPath aktualizuje kontur kształtu.
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();
}

Tworzenie własnego kształtu
Przykład buduje pięcioramienną gwiazdę przy użyciu GeometryPath. Naprzemienne promienie zewnętrzne i wewnętrzne o wartościach 100 i 50 punktów definiują szczyty i wklęsłości; krok 72 stopnie rozmieszcza pięć szczytów równomiernie. Ścieżka jest zamykana metodą GeometryPath.closeFigure i stosowana do prostokątnego kształtu przy pomocy IGeometryShape.setGeometryPath, zastępując jego obrys.
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();
}

Tworzenie złożonego własnego kształtu
Przykład definiuje dwie zamknięte ścieżki GeometryPath dla górnej i dolnej trzeciej części kształtu. Zastosowanie obu ścieżek przy pomocy IGeometryShape.setGeometryPaths tworzy jeden złożony kształt z przerwą w środkowej trzeciej części.
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();
}

Tworzenie własnego kształtu z zaokrąglonymi narożnikami
Przykład łączy proste odcinki z GeometryPath.arcTo w celu stworzenia kształtu z wklęsłymi narożnikami. Rozmiar każdego narożnika określa szerokość i wysokość łuku w punktach, a kąt -90° rysuje ćwiartkę elipsy w kierunku przeciwnym do ruchu wskazówek zegara. Gotowa ścieżka jest stosowana metodą IGeometryShape.setGeometryPath, a prezentacja zapisywana jest w formacie 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();
}
Sprawdzanie, czy geometria kształtu jest zamknięta
Poniższy pomocniczy kod sprawdza, czy każda niepusta ścieżka geometryczna kończy się odcinkiem zamknięcia. Odczytuje IGeometryPath.getPathData i porównuje polecenie ostatniego segmentu IPathSegment.getPathCommand z PathCommandType.Close. Zwraca false, gdy nie ma niepustych ścieżek. Kod sprawdza tylko ostatnie polecenie każdej ścieżki; nie analizuje wszystkich podfigur w obrębie ścieżki. Przykład wypisuje true dla prostokąta.
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();
}
Wyodrębnianie i przeglądanie elementów kształtu
Użyj IGeometryShape.createShapeElements do przeglądania istniejącego kształtu jako elementów zawierających punkty ścieżki i ich typy. Rzutuj każdy zwrócony IShapeElement na ShapeElement, aby pobrać tablice punktów i typów poprzez metody getPathPoints i getPathTypes. Taka reprezentacja jest przydatna przy analizie konturu lub przekazywaniu geometrii do własnych narzędzi rysunkowych.
Przykład otwiera input.pptx, znajduje pierwszy kształt geometryczny bezpośrednio na pierwszym slajdzie i wypisuje jego segmenty ścieżki. Użyj prezentacji zawierającej kształt z odcinkami prostymi i krzywymi, aby zobaczyć oba rodzaje wyników. Nie przeszukuje grup.
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; // Zachowaj typ segmentu, pomijając flagi.
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();
}
Tablice są powiązane indeksem: points[i] to punkt, a types[i] opisuje jego rolę. Typ 0 rozpoczyna figurę, a typ 1 rysuje linię od poprzedniego punktu do bieżącego. Segment Béziera trzeciego stopnia rozpoczyna się w poprzednim punkcie końcowym i wykorzystuje trzy kolejne wpisy typu 3: dwa punkty kontrolne oraz nowy punkt końcowy. Pętla zużywa te trzy wpisy razem i sprawdza punkt końcowy pod kątem zamknięcia.
Typy punktów zawierają także flagi. Maskuj wartość przy użyciu 0x07, aby określić typ odcinka, a sprawdzaj 0x80 oddzielnie, aby wykryć zamkniętą podścieżkę. Przykładowo, 129 (0x81) oznacza koniec linii zamykający podścieżkę, a 131 (0x83) oznacza koniec Béziera zamykający podścieżkę. Java przechowuje te flagi w bajtach ze znakiem; maskowanie zachowuje zamierzone wartości bitowe. Porównywanie surowej wartości jedynie z 1 lub 3 pominęłoby te przypadki. Inne flagi, takie jak kreska (0x10) i znacznik (0x20), nie zmieniają podstawowego typu odcinka.
Współrzędne i przekształcenia. Punkty mierzone są w punktach (1/72 cala), przy czym X rośnie w prawo, a Y w dół. Dla niepogrupowanego kształtu wyodrębnione współrzędne już zawierają pozycję zwróconą przez getX i getY oraz odzwierciedlają jego aktualną szerokość i wysokość. Przykładowo, nieobrócony prostokąt w (100, 200) o rozmiarze 120 × 80 ma granice konturu (100, 200)–(220, 280). Nie dodawaj ponownie pozycji kształtu. Odejmij jego X i Y, aby uzyskać współrzędne względem nieobróconej ramki.
Wyodrębnione punkty nie uwzględniają obrotu kształtu, zwracanego przez getRotation, ani odbić poziomych i pionowych. Aby odtworzyć wyświetlany kontur, zastosuj te przekształcenia względem środka kształtu. Dla kształtów grupowanych uwzględnij także mapowanie współrzędnych grupy i jej przekształcenia; nie zakładaj, że wyodrębnione punkty są ostatecznymi współrzędnymi slajdu ani nie stosuj podwójnego przesunięcia lub skalowania, jeśli już zostały uwzględnione w ramce dziecka.
Inspekcja a edycja. Wyodrębnione tablice opisują kontur; ich modyfikacja nie aktualizuje oryginalnego kształtu. Wybierz tę metodę, gdy potrzebujesz tablic punktów/typów do analizy lub własnego kodu rysującego. Użyj getGeometryPaths w przypadku, gdy potrzebujesz poleceń geometrycznych w lokalnym układzie współrzędnych kształtu lub chcesz edytować jego geometrię. Edytowane ścieżki aplikuj przy pomocy setGeometryPath lub setGeometryPaths.
FAQ
Co się stanie z wypełnieniem i obrysem po zastąpieniu geometrii?
Styl pozostaje przypisany do kształtu; zmienia się tylko kontur. Wypełnienie i obrys są automatycznie stosowane do nowej geometrii.
Jak prawidłowo obrócić własny kształt wraz z jego geometrią?
Użyj metody setRotation kształtu; geometria obraca się razem z kształtem, ponieważ jest związana z jego własnym układem współrzędnych.
Czy mogę skonwertować własny kształt na obraz, aby „zablokować” rezultat?
Tak. Wyeksportuj wybrany slide lub sam shape do formatu rastrowego; upraszcza to dalszą pracę z złożonymi geometriami.