Menggambar Grafik Vektor pada Halaman PDF
Menggambar Grafik Vektor pada Halaman PDF
Aspose.PDF FOSS untuk C++ mencakup sebuah API grafik vektor kecil untuk menggambar bentuk secara langsung ke halaman PDF saat dokumen sedang dibangun. Titik masuknya adalah Graph, sebuah kontainer yang ditempatkan pada halaman dan menampung koleksi objek Shape; tiga bentuk konkret — Circle, Ellipse, dan Line — diturunkan dari Shape dan masing-masing mengekspresikan geometri mereka secara berbeda. Gaya stroke dan fill per-bentuk berasal dari GraphInfo, dan kontainer Graph sendiri membawa BorderInfo untuk pembingkaian. Ini tidak terkait dengan rasterisasi halaman (BmpDevice, JpegDevice, TiffDevice), yang mengubah konten halaman yang ada menjadi format gambar raster alih-alih menggambar geometri baru.
Kontainer Grafik dan Menambahkan Bentuk ke Halaman
Graph menempatkan dan mengukur dirinya sendiri pada halaman melalui Left(), Top(), Width(), dan Height(), dan flag IsChangePosition() mengontrol apakah posisi itu dapat bergeser relatif terhadap konten halaman lainnya. Bentuk-bentuk yang digambarnya berada di vektor yang dikembalikan oleh Shapes() — std::vector<std::unique_ptr<Shape>> — yang diisi dengan cara membuat sebuah bentuk, mengkonfigurasinya, dan memindahkannya ke vektor tersebut. Setelah dibangun, Graph sendiri ditempatkan pada halaman melalui Page.Paragraphs().Add(), koleksi yang sama digunakan untuk konten tingkat halaman lainnya.
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/drawing/graph.hpp>
#include <aspose/pdf/drawing/circle.hpp>
using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Drawing;
Document doc;
Page page = doc.Pages().Add();
auto graph = std::make_shared<Graph>();
graph->Left(36.0);
graph->Top(36.0);
graph->Width(500.0);
graph->Height(300.0);
auto marker = std::make_unique<Circle>();
marker->PosX(60.0);
marker->PosY(60.0);
marker->Radius(30.0);
graph->Shapes().push_back(std::move(marker));
page.Paragraphs().Add(graph);
doc.Save("shapes.pdf");Menggambar Lingkaran dan Elips
Circle dan Ellipse masing-masing mengekspresikan geometri sebagai properti numerik sederhana alih-alih tipe titik atau persegi panjang bersama. Circle adalah titik tengah dan radius — PosX(), PosY(), Radius() — sedangkan Ellipse adalah kotak pembatas — Left(), Bottom(), Width(), Height(). Keduanya mewarisi CheckBounds(containerWidth, containerHeight) dari Shape, yang melaporkan apakah geometri bentuk saat ini muat di dalam kontainer dengan ukuran yang diberikan tanpa mengubah bentuk itu sendiri.
#include <aspose/pdf/drawing/circle.hpp>
#include <aspose/pdf/drawing/ellipse.hpp>
using namespace Aspose::Pdf::Drawing;
Circle circle;
circle.PosX(120.0);
circle.PosY(120.0);
circle.Radius(60.0);
bool circleFits = circle.CheckBounds(500.0, 300.0);
Ellipse ellipse;
ellipse.Left(220.0);
ellipse.Bottom(20.0);
ellipse.Width(250.0);
ellipse.Height(100.0);
bool ellipseFits = ellipse.CheckBounds(500.0, 300.0);Menggambar Garis dengan PositionArray
Line menyimpan geometri-nya secara berbeda dari Circle dan Ellipse: PositionArray() mengembalikan std::vector<float> datar yang memuat pasangan x, y untuk setiap titik yang dilalui garis, bukan sekumpulan properti bernama yang tetap. Dua titik (empat nilai) menggambar segmen lurus; pasangan tambahan menggambar jalur multi-segmen melalui titik-titik tersebut secara berurutan. Seperti bentuk lainnya, Line menimpa CheckBounds(containerWidth, containerHeight) dari Shape.
#include <aspose/pdf/drawing/line.hpp>
using namespace Aspose::Pdf::Drawing;
Line path;
path.PositionArray({0.0f, 0.0f, 250.0f, 0.0f, 125.0f, 200.0f});
bool pathFits = path.CheckBounds(500.0, 300.0);Menyetel Gaya Bentuk dengan GraphInfo dan BorderInfo
Setiap bentuk membaca dan menulis gaya stroke serta fill-nya melalui Shape.GraphInfo() / GraphInfo(value). GraphInfo secara default menjadi LineWidth() 1.0f dengan DashArray() kosong, dan juga menyediakan Color(), FillColor(), DashArray()/DashPhase() untuk stroke bergaris putus-putus, IsDoubled() untuk garis ganda, serta SkewAngleX()/SkewAngleY(), ScalingRateX()/ScalingRateY(), dan RotationAngle() untuk mengubah stroke. Graph sendiri membawa BorderInfo, yang diatur melalui Border(), yang mengelompokkan satu GraphInfo per tepi — Left(), Right(), Top(), Bottom() — plus RoundedBorderRadius(), dan dapat dibangun dengan menyebutkan tepi mana yang akan di-styling dengan flag BorderSide (BorderSide::Left | BorderSide::Right, atau BorderSide::All untuk setiap tepi).
#include <aspose/pdf/graph_info.hpp>
#include <aspose/pdf/border_info.hpp>
#include <aspose/pdf/border_side.hpp>
#include <aspose/pdf/color.hpp>
using namespace Aspose::Pdf;
GraphInfo stroke;
stroke.LineWidth(2.5f);
stroke.Color(Color::FromRgb(1.0, 0.0, 0.0));
stroke.DashArray({3, 2});
stroke.DashPhase(1);
stroke.IsDoubled(true);
// Style only the left and right edges of the container border.
BorderInfo border{BorderSide::Left | BorderSide::Right, 3.0f};
border.RoundedBorderRadius(4.0);
graph->GraphInfo(stroke);
graph->Border(border);Tips dan Praktik Terbaik
- Panggil
CheckBoundsterhadapWidth()/Height()milikGraphsendiri, bukan kotak media penuh halaman — pemeriksaan ini memvalidasi geometri bentuk terhadap ukuran kontainer apa pun yang Anda berikan, tidak secara otomatis melihat halaman. - Tambahkan bentuk ke
Shapes()sebelum menambahkanGraphkePage.Paragraphs()— membuatCircle,Ellipse, atauLinetidak memberikan efek visual hingga bentuk tersebut ditambahkan keGraphmiliknya danGraphtersebut ditambahkan ke halaman. - Kelompokkan bentuk terkait di bawah satu
Graphalih-alih satuGraphper bentuk;Left()/Top()/Width()/Height()menempatkan seluruh kontainer sekaligus, dan setiap bentuk dalamShapes()digambar relatif terhadapnya. - Atur
Shape.GraphInfo()secara eksplisit untuk bentuk yang memerlukan isi yang terlihat atau stroke non-default —GraphInfodefault memiliki lebar garis1.0f, tanpa isi, danDashArray()kosong. - Bangun
Line.PositionArray()sebagai pasanganx0, y0, x1, y1, …dalam urutan jalur yang harus digambar — vektor dengan panjang ganjil menggambarkan titik yang tidak lengkap.
Masalah Umum
| Masalah | Penyebab | Perbaikan |
|---|---|---|
Sebuah Circle, Ellipse, atau Line tidak pernah muncul di halaman yang disimpan | Bentuk telah dibuat tetapi tidak pernah ditambahkan ke Graph’s Shapes(), atau Graph tidak pernah ditambahkan ke halaman | Dorong bentuk ke graph->Shapes() dan panggil page.Paragraphs().Add(graph) |
| Bentuk digambar dengan goresan hitam tipis bawaan | Shape.GraphInfo() tidak pernah diatur | Panggil shape->GraphInfo(customGraphInfo) sebelum menambahkan bentuk ke Shapes() |
Line hilang atau tampak seperti satu titik | PositionArray() memiliki kurang dari dua pasangan (x, y), atau jumlah nilai yang ganjil | Berikan setidaknya empat nilai sebagai x0, y0, x1, y1 |
| Hanya sebagian tepi batas kontainer yang diberi gaya | BorderInfo dibangun dengan topeng BorderSide yang mengecualikan beberapa tepi | Gunakan BorderSide::All, atau gabungkan dengan OR setiap flag BorderSide yang diperlukan |
CheckBounds secara tak terduga mengembalikan false | Dimensi yang diberikan ke CheckBounds tidak cocok dengan kontainer tempat bentuk sebenarnya digambar | Lewati Width()/Height() saat ini milik Graph |
FAQ
Apa perbedaan antara Circle dan AnnotationType::Circle?
Circle (panduan ini) adalah bentuk gambar yang menggambar langsung ke dalam konten halaman melalui Graph. AnnotationType::Circle dan CircleAnnotation termasuk dalam API anotasi terpisah dan mewakili anotasi markup berbentuk lingkaran — keduanya tidak berhubungan meskipun memiliki nama yang sama.
Apakah satu Graph dapat berisi lebih dari satu bentuk?
Ya. Graph.Shapes() mengembalikan std::vector<std::unique_ptr<Shape>> lengkap untuk kontainer tersebut, dan campuran apa pun dari instance Circle, Ellipse, dan Line dapat ditambahkan ke dalamnya sebelum Graph ditambahkan ke halaman.
Apakah Circle dan Ellipse berbagi tipe geometri?
No. Circle adalah titik pusat dan radius (PosX, PosY, Radius); Ellipse adalah kotak pembatas (Left, Bottom, Width, Height). Keduanya berasal dari Shape, tetapi tidak ada yang berbagi titik atau tipe persegi panjang yang sama dengan yang lain.
Apakah menggambar bentuk dengan Graph sama dengan merender halaman menjadi gambar?
Tidak. Graph, Shape, Circle, Ellipse, dan Line membangun geometri vektor baru ke dalam konten halaman saat dokumen dihasilkan. Mengonversi halaman yang ada menjadi gambar raster adalah kemampuan terpisah, yang ditangani oleh BmpDevice, JpegDevice, dan TiffDevice.
Apa yang dilakukan GraphInfo.IsDoubled()?
Ini menandai goresan sebagai garis ganda alih-alih mengubah properti goresan lainnya. Ini adalah flag boolean yang dibaca dan diatur melalui IsDoubled() / IsDoubled(value) bersama dengan properti goresan GraphInfo lainnya.
Ringkasan API Reference
| Kelas/Metode | Deskripsi |
|---|---|
Graph | Kontainer bentuk ditempatkan pada halaman; memposisikan dirinya dengan Left(), Top(), Width(), Height() |
Graph.Shapes() | Mengembalikan std::vector<std::unique_ptr<Shape>> yang digambar oleh kontainer ini |
Graph.GraphInfo() / GraphInfo(value) | Mendapatkan/mengatur styling stroke dan fill milik kontainer |
Graph.Border() / Border(value) | Mendapatkan/mengatur BorderInfo yang membingkai kontainer |
Shape | Basis abstrak untuk Circle, Ellipse, dan Line; mengekspos GraphInfo() dan CheckBounds() |
Shape.CheckBounds(w, h) | Melaporkan apakah geometri bentuk cocok di dalam wadah dengan lebar/tinggi yang diberikan |
Circle | Bentuk lingkaran: PosX(), PosY(), Radius() |
Ellipse | Bentuk elips: kotak pembatas melalui Left(), Bottom(), Width(), Height() |
Line | Bentuk garis/jalur: PositionArray(), sebuah std::vector<float> datar dari koordinat x, y |
GraphInfo | Gaya garis/pengisian: LineWidth(), Color(), FillColor(), DashArray(), DashPhase(), IsDoubled(), RotationAngle(), SkewAngleX()/SkewAngleY(), ScalingRateX()/ScalingRateY() |
BorderInfo | Batas kontainer per-edge: Left(), Right(), Top(), Bottom() (masing-masing GraphInfo), dan RoundedBorderRadius() |
BorderSide | Enum yang memilih tepi saat membangun BorderInfo: None, Left, Top, Right, Bottom, All, Box |