Sesuaikan Bentuk Presentasi di .NET
Ikhtisar
Artikel ini menjelaskan cara menyesuaikan bentuk presentasi di Aspose.Slides dengan mengedit geometri bentuk melalui titik edit dan jalur geometri. Ini menunjukkan cara bekerja dengan GeometryPath dan IGeometryPath untuk memodifikasi bentuk yang ada, melakukan operasi penyuntingan jalur dasar, menambah atau menghapus titik, dan menerapkan geometri yang diperbarui kembali ke sebuah bentuk.
Artikel ini juga mendemonstrasikan cara membuat bentuk khusus dan komposit, membangun bentuk dengan sudut melengkung, menentukan apakah geometri sebuah bentuk tertutup, dan menggunakan konversi warisan antara GeometryPath dan GraphicsPath untuk skenario penyesuaian geometri tambahan.
Ubah Bentuk Menggunakan Titik Edit
Di PowerPoint, Anda dapat menggunakan Edit Points untuk memodifikasi sebuah persegi:
- Pindahkan sudut ke dalam atau ke luar.
- Sesuaikan kelengkungan pada sebuah titik.
- Tambahkan titik baru.
Mengedit titik memungkinkan Anda memodifikasi kontur bentuk atau menggunakan bentuk yang ada sebagai dasar untuk bentuk baru.
Tips Penyuntingan Bentuk

Saat menyunting bentuk PowerPoint, ingat konsep-konsep berikut:
- Sebuah bentuk (atau jalurnya) dapat berupa tertutup atau terbuka.
- Jalur sebuah bentuk terdiri dari titik jangkar yang dihubungkan oleh segmen.
- Sebuah segmen dapat lurus atau melengkung. Titik jangkar dan pegangan kontrol menentukan bentuknya.
- Titik jangkar dapat berupa titik sudut, titik lurus, atau titik halus:
- Pada titik sudut, segmen yang bersebelahan dapat bertemu pada sebuah sudut.
- Pada titik halus, dua pegangan kontrol sejajar dan berjarak sama dari titik jangkar.
- Pada titik lurus, dua pegangan kontrol sejajar tetapi dapat memiliki jarak yang berbeda dari titik jangkar.
- Memindahkan titik jangkar atau menyesuaikan pegangan mereka mengubah kontur bentuk.
Untuk menyunting bentuk PowerPoint melalui titik edit, Aspose.Slides menyediakan kelas GeometryPath dan antarmuka IGeometryPath.
- Sebuah instance GeometryPath mewakili jalur geometri dari objek IGeometryShape.
- Untuk mengambil GeometryPath dari instance IGeometryShape, Anda dapat menggunakan metode IGeometryShape.GetGeometryPaths.
- Untuk menetapkan GeometryPath pada sebuah bentuk, Anda dapat menggunakan metode berikut: IGeometryShape.SetGeometryPath untuk bentuk dengan satu jalur dan IGeometryShape.SetGeometryPaths untuk bentuk dengan beberapa jalur.
- Untuk menambahkan segmen, Anda dapat menggunakan metode di bawah IGeometryPath.
- Dengan menggunakan properti IGeometryPath.Stroke dan IGeometryPath.FillMode, Anda dapat mengatur tampilan jalur geometri.
- Dengan menggunakan properti IGeometryPath.PathData, Anda dapat mengambil jalur geometri dari sebuah GeometryShape sebagai array segmen jalur.
- Pada versi warisan yang mendukung metode konversi di bawah, Anda dapat mengonversi GeometryPath ke GraphicsPath.
- Gunakan metode GeometryPathToGraphicsPath dan GraphicsPathToGeometryPath (dari kelas ShapeUtil) untuk mengonversi antara GeometryPath dan GraphicsPath.
Operasi Penyuntingan Sederhana
Gunakan metode berikut untuk menyunting jalur geometri. Overload yang menerima indeks menyisipkan segmen pada posisi berbasis nol dalam array segmen jalur.
| Operation | Method |
|---|---|
| Menambahkan atau menyisipkan garis lurus. | GeometryPath.LineTo |
| Menambahkan atau menyisipkan kurva Bézier kubik dengan dua titik kontrol dan titik akhir. | GeometryPath.CubicBezierTo |
| Menambahkan atau menyisipkan kurva Bézier kuadratik dengan satu titik kontrol dan titik akhir. | GeometryPath.QuadraticBezierTo |
| Menambahkan busur elips dengan dimensi dan sudut yang ditentukan dalam derajat. | GeometryPath.ArcTo |
| Menutup gambar saat ini dengan menghubungkan titik akhirnya ke titik awal. | GeometryPath.CloseFigure |
| Menetapkan titik mulai sebuah gambar. | GeometryPath.MoveTo |
| Menghapus segmen pada indeks berbasis nol. | GeometryPath.RemoveAt |
Menambahkan Titik Kustom ke Sebuah Bentuk
Contoh ini menyisipkan dua titik ke dalam bentuk persegi panjang menggunakan GeometryPath.LineTo dan menerapkan jalur yang diedit dengan IGeometryShape.SetGeometryPath. Koordinat bersifat lokal terhadap bentuk: kedua titik baru berada di pusatnya, 100 poin dari kiri dan 50 poin dari atas. Indeks segmen 1 dan 4 menempatkannya pada tepi atas dan bawah, menarik tepi tersebut ke dalam.
using Aspose.Slides;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 100, 100, 200, 100);
var geometryPath = shape.GetGeometryPaths()[0];
geometryPath.LineTo(100, 50, 1);
geometryPath.LineTo(100, 50, 4);
shape.SetGeometryPath(geometryPath);

Menghapus Titik dari Sebuah Bentuk
Contoh ini mengubah kontur berbentuk hati dengan menghapus segmen pada indeks berbasis nol 2 menggunakan GeometryPath.RemoveAt. Menerapkan jalur yang dimodifikasi dengan IGeometryShape.SetGeometryPath memperbarui kontur bentuk.
using Aspose.Slides;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var shape = slide.Shapes.AddAutoShape(ShapeType.Heart, 100, 100, 300, 300);
var path = shape.GetGeometryPaths()[0];
path.RemoveAt(2);
shape.SetGeometryPath(path);

Membuat Bentuk Kustom
Contoh ini membangun bintang lima sudut dengan GeometryPath. Radius luar dan dalam yang bergantian sebesar 100 dan 50 poin menentukan ujung dan cekungan; langkah 72 derajat menempatkan lima ujung secara merata. Jalur ditutup dengan GeometryPath.CloseFigure dan diterapkan ke bentuk persegi panjang menggunakan IGeometryShape.SetGeometryPath, menggantikan konturnya.
using System;
using System.Collections.Generic;
using System.Drawing;
using Aspose.Slides;
var points = new List<PointF>();
var outerRadius = 100f;
var innerRadius = 50f;
var angleStep = 72;
for (var angle = -90; angle < 270; angle += angleStep)
{
var radians = angle * (Math.PI / 180f);
var x = outerRadius * Math.Cos(radians);
var y = outerRadius * Math.Sin(radians);
points.Add(new PointF((float)x + outerRadius, (float)y + outerRadius));
radians = Math.PI * (angle + angleStep / 2) / 180.0;
x = innerRadius * Math.Cos(radians);
y = innerRadius * Math.Sin(radians);
points.Add(new PointF((float)x + outerRadius, (float)y + outerRadius));
}
var starPath = new GeometryPath();
starPath.MoveTo(points[0]);
for (var i = 1; i < points.Count; i++)
{
starPath.LineTo(points[i]);
}
starPath.CloseFigure();
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 100, 100, outerRadius * 2, outerRadius * 2);
shape.SetGeometryPath(starPath);

Membuat Bentuk Kustom Komposit
Contoh ini mendefinisikan dua objek GeometryPath tertutup untuk sepertiga atas dan bawah sebuah bentuk. Menerapkan kedua jalur dengan IGeometryShape.SetGeometryPaths menghasilkan satu bentuk komposit dengan celah pada sepertiga tengahnya.
using Aspose.Slides;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 100, 100, 200, 100);
var topPath = new GeometryPath();
topPath.MoveTo(0, 0);
topPath.LineTo(shape.Width, 0);
topPath.LineTo(shape.Width, shape.Height / 3);
topPath.LineTo(0, shape.Height / 3);
topPath.CloseFigure();
var bottomPath = new GeometryPath();
bottomPath.MoveTo(shape.Height / 3 * 2);
bottomPath.LineTo(shape.Width, shape.Height / 3 * 2);
bottomPath.LineTo(shape.Width, shape.Height);
bottomPath.LineTo(0, shape.Height);
bottomPath.CloseFigure();
shape.SetGeometryPaths(new GeometryPath[] { topPath, bottomPath });

Membuat Bentuk Kustom dengan Sudut Melengkung
Contoh ini menggabungkan segmen lurus dengan GeometryPath.ArcTo untuk membuat bentuk dengan sudut melengkung ke dalam. Setiap ukuran sudut menentukan lebar dan tinggi busur dalam poin, dan sapuan -90 derajat menggambar seperempat elips berlawanan arah jarum jam. Jalur yang selesai diterapkan dengan IGeometryShape.SetGeometryPath, dan presentasi disimpan dalam format PPTX.
using System.Drawing;
using Aspose.Slides;
using Aspose.Slides.Export;
var shapeX = 20f;
var shapeY = 20f;
var shapeWidth = 300f;
var shapeHeight = 200f;
var leftTopSize = 50f;
var rightTopSize = 20f;
var rightBottomSize = 40f;
var leftBottomSize = 10f;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var topLeft = new PointF(leftTopSize, 0);
var topRight = new PointF(shapeWidth - rightTopSize, 0);
var rightBottom = new PointF(shapeWidth, shapeHeight - rightBottomSize);
var bottomLeft = new PointF(leftBottomSize, shapeHeight);
var leftTop = new PointF(0, leftTopSize);
var 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();
var shape = slide.Shapes.AddAutoShape(ShapeType.Custom, shapeX, shapeY, shapeWidth, shapeHeight);
shape.SetGeometryPath(geometryPath);
presentation.Save("output.pptx", SaveFormat.Pptx);
Menemukan Apakah Geometri Bentuk Tertutup
Pembantu berikut memeriksa apakah setiap jalur geometri yang tidak kosong berakhir dengan segmen penutup. Ia membaca IGeometryPath.PathData dan membandingkan perintah segmen akhir IPathSegment.PathCommand dengan PathCommandType.Close. Ia mengembalikan false ketika tidak ada jalur yang tidak kosong. Pemeriksaan ini melihat perintah akhir tiap jalur; tidak memeriksa setiap subgambar di dalam jalur. Contoh mencetak True untuk persegi panjang.
using System;
using Aspose.Slides;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 100, 100, 200, 100);
Console.WriteLine(IsGeometryClosed(shape));
bool IsGeometryClosed(IGeometryShape geometryShape)
{
var hasNonemptyPath = false;
foreach (var geometryPath in geometryShape.GetGeometryPaths())
{
var segments = geometryPath.PathData;
if (segments.Length == 0)
{
continue;
}
hasNonemptyPath = true;
var lastSegment = segments[segments.Length - 1];
if (lastSegment.PathCommand != PathCommandType.Close)
{
return false;
}
}
return hasNonemptyPath;
}
Mengekstrak dan Memeriksa Elemen Bentuk
Gunakan IGeometryShape.CreateShapeElements untuk memeriksa bentuk yang ada sebagai elemen yang berisi titik jalur dan tipe titik. Cast setiap IShapeElement yang dikembalikan ke ShapeElement untuk membaca array PathPoints dan PathTypesnya. Representasi ini berguna untuk analisis kontur atau meneruskan geometri ke alat gambar kustom.
Contoh membuka sebuah presentasi, menemukan bentuk geometri pertama langsung pada slide pertama, dan mencetak segmen jalurnya. Gunakan presentasi yang berisi bentuk dengan segmen lurus dan melengkung untuk melihat kedua jenis output. Ia tidak mencari di dalam grup.
using System;
using System.Linq;
using Aspose.Slides;
using var presentation = new Presentation("input.pptx");
var slide = presentation.Slides[0];
var shape = slide.Shapes.OfType<IGeometryShape>().FirstOrDefault();
if (shape == null)
{
Console.WriteLine("No geometry shape found on the first slide.");
return;
}
foreach (IShapeElement element in shape.CreateShapeElements())
{
var shapeElement = (ShapeElement)element;
var points = shapeElement.PathPoints;
var types = shapeElement.PathTypes;
Console.WriteLine("Shape element:");
for (var i = 0; i < points.Length; i++)
{
var pointType = types[i] & 0x07; // Pertahankan tipe segmen, kecuali flag.
switch (pointType)
{
case 0:
Console.WriteLine($"Start figure at {points[i]}");
break;
case 1:
Console.WriteLine($"Line to {points[i]}");
break;
case 3:
Console.WriteLine($"Cubic Bezier: controls {points[i]}, {points[i + 1]}; end {points[i + 2]}");
i += 2; // Konsumsi kedua titik kontrol dan titik akhir.
break;
}
if ((types[i] & 0x80) != 0)
{
Console.WriteLine("Close subpath back to its starting point.");
}
}
}
Array tersebut berkorespondensi berdasarkan indeks: points[i] adalah sebuah titik dan types[i] menjelaskan perannya. Tipe 0 memulai sebuah gambar, dan tipe 1 menggambar garis dari titik sebelumnya ke titik saat ini. Segmen Bézier kubik dimulai pada titik akhir sebelumnya dan menggunakan tiga entri tipe-3 berurutan: dua titik kontrol diikuti oleh titik akhir baru. Loop mengonsumsi ketiga entri tersebut bersama-sama dan memeriksa titik akhir untuk penutupan.
Tipe titik juga mengandung flag. Lakukan mask dengan 0x07 untuk mengidentifikasi tipe segmen, dan uji 0x80 secara terpisah untuk mendeteksi subpath tertutup. Misalnya, 129 (0x81) berarti titik akhir garis yang menutup subpath, dan 131 (0x83) berarti titik akhir Bézier yang menutup satu. Membandingkan nilai mentah hanya dengan 1 atau 3 akan melewatkan kasus ini. Flag lain, seperti dash (0x10) dan marker (0x20), tidak mengubah tipe segmen dasar.
Koordinat dan transformasi.
Titik diukur dalam poin (1/72 inci), dengan X bertambah ke kanan dan Y bertambah ke bawah. Untuk bentuk yang tidak dikelompokkan, koordinat yang diekstrak sudah mencakup posisi X dan Ynya serta mencerminkan lebar dan tinggi saat ini. Misalnya, persegi panjang yang tidak diputar pada (100, 200) dengan ukuran 120 × 80 memiliki batas kontur (100, 200)–(220, 280). Jangan menambahkan posisi bentuk lagi. Kurangi X dan Y-nya untuk memperoleh koordinat relatif terhadap kerangka yang tidak diputar.
Titik yang diekstrak tidak menerapkan Rotation bentuk atau flip horizontal dan vertikal. Untuk mereproduksi kontur yang ditampilkan, terapkan transformasi tersebut di sekitar pusat bentuk. Untuk bentuk yang dikelompokkan, perhitungkan juga pemetaan koordinat grup dan transformasinya; jangan berasumsi bahwa titik yang diekstrak adalah koordinat slide akhir yang dirender atau menerapkan translasi atau skala dua kali jika sudah tercermin dalam kerangka anak.
Pemeriksaan vs penyuntingan.
Array yang diekstrak menggambarkan kontur; mengubahnya tidak memperbarui bentuk asli. Pilih pendekatan ini ketika analisis atau kode gambar Anda memerlukan array titik/tipe. Gunakan GetGeometryPaths ketika Anda memerlukan perintah geometri dalam sistem koordinat lokal bentuk atau ingin menyunting geometriannya. Terapkan jalur yang disunting melalui SetGeometryPath atau SetGeometryPaths.
Mengonversi GeometryPath ke GraphicsPath (System.Drawing.Drawing2D)
Contoh berikut memerlukan assembly Aspose.Slides for .NET versi warisan yang mendukung ShapeUtil.GraphicsPathToGeometryPath, seperti versi 25.10, dan lingkungan Windows dengan System.Drawing.Common. Metode konversi dihapus dalam version 25.11.
Contoh ini menggabungkan kontur persegi panjang dengan teks yang dikonversi menjadi geometri. IGeometryPath.FillMode kontur diatur untuk menonaktifkan isinya. Sebuah GraphicsPath menyimpan kontur teks, yang dikonversi oleh ShapeUtil.GraphicsPathToGeometryPath menjadi jalur geometri berisi. Menerapkan kedua jalur dengan IGeometryShape.SetGeometryPaths menghasilkan satu bentuk yang berisi persegi panjang dan teks. Untuk konversi ke arah sebaliknya, gunakan ShapeUtil.GeometryPathToGraphicsPath.
using System.Drawing;
using System.Drawing.Drawing2D;
using Aspose.Slides;
using Aspose.Slides.Util;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 100, 100, 300, 100);
var originalPath = shape.GetGeometryPaths()[0];
originalPath.FillMode = PathFillModeType.None;
using var graphicsPath = new GraphicsPath();
using var fontFamily = new FontFamily("Arial");
using var stringFormat = StringFormat.GenericDefault;
graphicsPath.AddString("Text in shape", fontFamily, (int)FontStyle.Bold, 40, new PointF(10, 10), stringFormat);
var textPath = ShapeUtil.GraphicsPathToGeometryPath(graphicsPath);
textPath.FillMode = PathFillModeType.Normal;
shape.SetGeometryPaths(new[] { originalPath, textPath });

FAQ
Apa yang akan terjadi pada isi dan kontur setelah mengganti geometri?
Gaya tetap berada pada bentuk; hanya kontur yang berubah. Isi dan kontur secara otomatis diterapkan pada geometri baru.
Bagaimana cara memutar bentuk kustom secara benar bersama geometrianya?
Gunakan properti Rotation bentuk; geometri berputar bersama bentuk karena terikat pada sistem koordinat bentuk itu sendiri.
Bisakah saya mengonversi bentuk kustom menjadi gambar untuk “mengunci” hasilnya?
Ya. Ekspor area slide yang diperlukan atau bentuk itu sendiri ke format raster; ini menyederhanakan pekerjaan selanjutnya dengan geometri yang kompleks.