Vẽ Đồ Họa Vector trên Trang PDF
Vẽ Đồ Họa Vector trên Trang PDF
Aspose.PDF FOSS cho C++ bao gồm một API đồ họa vector nhỏ để vẽ các hình dạng trực tiếp lên trang PDF trong quá trình xây dựng tài liệu. Điểm vào là Graph, một container đặt trên trang và chứa một tập hợp các đối tượng Shape; ba hình dạng cụ thể — Circle, Ellipse và Line — kế thừa từ Shape và mỗi cái biểu diễn hình học của mình theo cách khác nhau. Kiểu dáng nét và màu nền cho từng hình được lấy từ GraphInfo, và container Graph tự nó mang một BorderInfo để đóng khung. Điều này không liên quan đến raster hóa trang (BmpDevice, JpegDevice, TiffDevice), vốn chuyển đổi nội dung trang hiện có sang các định dạng ảnh raster thay vì vẽ hình học mới.
Container Đồ Thị và Thêm Hình Dạng vào Trang
Graph định vị và xác định kích thước của mình trên trang thông qua Left(), Top(), Width() và Height(), và cờ IsChangePosition() của nó kiểm soát việc vị trí này có thể dịch chuyển so với nội dung trang khác hay không. Các hình dạng mà nó vẽ tồn tại trong vector do Shapes() trả về — std::vector<std::unique_ptr<Shape>> — được lấp đầy bằng cách tạo một hình dạng, cấu hình nó, và đưa nó vào vector đó. Khi đã được xây dựng, Graph tự nó được đặt trên trang qua Page.Paragraphs().Add(), cùng bộ sưu tập được dùng cho các nội dung cấp trang khác.
#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");Vẽ Các Hình Tròn và Hình Bầu Dục
Circle và Ellipse mỗi cái biểu diễn hình học dưới dạng các thuộc tính số thuần túy thay vì một kiểu điểm hoặc hình chữ nhật chung. Circle là một điểm trung tâm và bán kính — PosX(), PosY(), Radius() — trong khi Ellipse là một hộp bao — Left(), Bottom(), Width(), Height(). Cả hai đều kế thừa CheckBounds(containerWidth, containerHeight) từ Shape, cái mà báo cáo liệu hình dạng hiện tại có vừa trong một container có kích thước cho trước mà không thay đổi hình dạng đó.
#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);Vẽ Đường Thẳng với PositionArray
Line lưu trữ hình học của nó khác với Circle và Ellipse: PositionArray() trả về một std::vector<float> phẳng chứa một cặp x, y cho mỗi điểm mà đường đi qua, thay vì một tập hợp các thuộc tính có tên cố định. Hai điểm (bốn giá trị) vẽ một đoạn thẳng; các cặp bổ sung vẽ một đường đa đoạn qua các điểm đó theo thứ tự. Giống như các hình khác, Line ghi đè CheckBounds(containerWidth, containerHeight) từ 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);Định dạng các hình dạng với GraphInfo và BorderInfo
Mỗi hình dạng đọc và ghi kiểu dáng nét vẽ và tô đầy thông qua Shape.GraphInfo() / GraphInfo(value). GraphInfo mặc định là một LineWidth() của 1.0f với một DashArray() trống, và cũng cung cấp Color(), FillColor(), DashArray()/DashPhase() cho nét đứt, IsDoubled() cho đường đôi, và SkewAngleX()/SkewAngleY(), ScalingRateX()/ScalingRateY(), và RotationAngle() để biến đổi nét vẽ. Graph tự nó chứa một BorderInfo, được đặt qua Border(), nhóm một GraphInfo cho mỗi cạnh — Left(), Right(), Top(), Bottom() — cộng thêm một RoundedBorderRadius(), và có thể được tạo bằng cách chỉ định các cạnh cần định dạng với cờ BorderSide (BorderSide::Left | BorderSide::Right, hoặc BorderSide::All cho mọi cạnh).
#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);Mẹo và Thực hành Tốt nhất
- Gọi
CheckBoundstrênWidth()/Height()củaGraphsở hữu, không phải toàn bộ khung media của trang — kiểm tra xác thực hình học của một hình dựa trên kích thước container bạn truyền vào, nó không tự động xem xét trang. - Thêm các hình vào
Shapes()trước khi thêmGraphvàoPage.Paragraphs()— việc tạo mộtCircle,EllipsehoặcLinekhông có hiệu ứng nào cho tới khi nó vừa được nối vàoGraphsở hữu vàGraphđó được thêm vào một trang. - Nhóm các hình liên quan dưới một
Graphduy nhất thay vì mộtGraphcho mỗi hình;Left()/Top()/Width()/Height()định vị toàn bộ container một lần, và mọi hình trongShapes()được vẽ tương đối so với nó. - Thiết lập
Shape.GraphInfo()một cách rõ ràng cho các hình cần tô đầy nhìn thấy hoặc nét vẽ không mặc định —GraphInfomặc định có độ rộng đường1.0f, không có tô, và mộtDashArray()trống. - Xây dựng
Line.PositionArray()dưới dạng các cặpx0, y0, x1, y1, …theo thứ tự đường dẫn cần vẽ — một vector có độ dài lẻ mô tả một điểm không hoàn chỉnh.
Các vấn đề thường gặp
| Vấn đề | Nguyên nhân | Cách khắc phục |
|---|---|---|
Một Circle, Ellipse, hoặc Line không bao giờ xuất hiện trên trang đã lưu | Hình dạng đã được tạo nhưng không bao giờ được gắn vào Shapes() của Graph, hoặc Graph không bao giờ được thêm vào trang | Đẩy hình dạng lên graph->Shapes() và gọi page.Paragraphs().Add(graph) |
| Hình dạng được vẽ với đường viền mỏng đen mặc định | Shape.GraphInfo() không bao giờ được đặt | Gọi shape->GraphInfo(customGraphInfo) trước khi thêm hình vào Shapes() |
Line bị thiếu hoặc trông giống một điểm duy nhất | PositionArray() có ít hơn hai cặp (x, y), hoặc số giá trị lẻ | Cung cấp ít nhất bốn giá trị dưới dạng x0, y0, x1, y1 |
| Chỉ một số cạnh của viền container được định kiểu | BorderInfo được xây dựng bằng mặt nạ BorderSide loại trừ một số cạnh | Sử dụng BorderSide::All, hoặc OR tất cả các cờ BorderSide cần thiết |
CheckBounds bất ngờ trả về false | Kích thước được truyền vào CheckBounds không khớp với container mà hình dạng thực sự được vẽ trong đó | Chuyển Width()/Height() hiện tại của Graph sở hữu |
FAQ
Sự khác nhau giữa Circle và AnnotationType::Circle là gì?
Circle (hướng dẫn này) là một hình vẽ mà vẽ trực tiếp vào nội dung trang thông qua một Graph. AnnotationType::Circle và CircleAnnotation thuộc về một API chú thích riêng biệt và đại diện cho một chú thích dạng vòng tròn — hai thứ này không liên quan mặc dù có cùng tên.
Một Graph duy nhất có thể chứa nhiều hơn một hình không?
Có. Graph.Shapes() trả về toàn bộ std::vector<std::unique_ptr<Shape>> cho container đó, và bất kỳ sự kết hợp nào của các thể hiện Circle, Ellipse và Line đều có thể được thêm vào trước khi Graph được đưa vào trang.
Circle và Ellipse có cùng loại hình học không?
Không. Circle là một điểm trung tâm và bán kính (PosX, PosY, Radius); Ellipse là một hộp bao quanh (Left, Bottom, Width, Height). Cả hai đều xuất phát từ Shape, nhưng không có điểm chung hay loại hình chữ nhật nào chung với nhau.
Việc vẽ các hình dạng bằng Graph có giống như việc render một trang thành hình ảnh không?
Không. Graph, Shape, Circle, Ellipse và Line xây dựng hình học vector mới vào nội dung của trang khi tài liệu được tạo. Việc chuyển đổi một trang hiện có thành hình ảnh raster là một khả năng riêng biệt, được xử lý bởi BmpDevice, JpegDevice và TiffDevice.
Hàm GraphInfo.IsDoubled() làm gì?
Nó đánh dấu nét vẽ là một đường gấp đôi thay vì thay đổi bất kỳ thuộc tính nét vẽ nào khác. Đây là một cờ boolean được đọc và thiết lập qua IsDoubled() / IsDoubled(value) cùng với các thuộc tính nét vẽ GraphInfo khác.
API Reference Tóm tắt
| Lớp/Phương thức | Mô tả |
|---|---|
Graph | Container hình dạng được đặt trên trang; định vị bản thân bằng Left(), Top(), Width(), Height() |
Graph.Shapes() | Trả về std::vector<std::unique_ptr<Shape>> do container này vẽ |
Graph.GraphInfo() / GraphInfo(value) | Lấy/đặt kiểu stroke và fill của container |
Graph.Border() / Border(value) | Lấy/đặt BorderInfo đóng khung container |
Shape | Cơ sở trừu tượng cho Circle, Ellipse và Line; công khai GraphInfo() và CheckBounds() |
Shape.CheckBounds(w, h) | Báo cáo liệu hình học của hình dạng có vừa trong một container có độ rộng/chiều cao cho trước hay không |
Circle | Hình tròn: PosX(), PosY(), Radius() |
Ellipse | Hình elip: hộp bao qua Left(), Bottom(), Width(), Height() |
Line | Hình đường/đường dẫn: PositionArray(), một std::vector<float> phẳng của các tọa độ x, y |
GraphInfo | Kiểu dáng nét vẽ/lấp đầy: LineWidth(), Color(), FillColor(), DashArray(), DashPhase(), IsDoubled(), RotationAngle(), SkewAngleX()/SkewAngleY(), ScalingRateX()/ScalingRateY() |
BorderInfo | Viền container mỗi cạnh: Left(), Right(), Top(), Bottom() (mỗi là GraphInfo), cộng thêm RoundedBorderRadius() |
BorderSide | Enum chọn các cạnh khi xây dựng một BorderInfo: None, Left, Top, Right, Bottom, All, Box |