วาดกราฟิกเวกเตอร์บนหน้า PDF
วาดกราฟิกเวกเตอร์บนหน้า PDF
Aspose.PDF FOSS for C++ มี API กราฟิกเวกเตอร์ขนาดเล็กสำหรับวาดรูปทรงโดยตรงบนหน้า PDF ขณะกำลังสร้างเอกสาร จุดเริ่มต้นคือ Graph ซึ่งเป็นคอนเทนเนอร์ที่วางบนหน้าและเก็บชุดของวัตถุ Shape; สามรูปทรงเชิงรูปธรรม — Circle, Ellipse, และ Line — สืบทอดจาก Shape และแต่ละรูปแสดงเรขาคณิตของตนแตกต่างกัน การกำหนดสไตล์เส้นและเติมสีต่อรูปมาจาก GraphInfo, และคอนเทนเนอร์ Graph เองมี BorderInfo สำหรับการกรอบ สิ่งนี้ไม่มีความเกี่ยวข้องกับการแรสเตอร์หน้ากระดาษ (BmpDevice, JpegDevice, TiffDevice) ซึ่งแปลงเนื้อหาหน้าที่มีอยู่เป็นรูปแบบภาพแรสเตอร์แทนการวาดเรขาคณิตใหม่.
คอนเทนเนอร์กราฟและการเพิ่มรูปทรงลงบนหน้า
Graph กำหนดตำแหน่งและขนาดของตนบนหน้าโดยใช้ Left(), Top(), Width(), และ Height(), และแฟล็ก IsChangePosition() ของมันควบคุมว่าตำแหน่งนั้นสามารถเปลี่ยนแปลงสัมพันธ์กับเนื้อหาอื่นในหน้าได้หรือไม่ รูปทรงที่มันวาดจะอยู่ในเวกเตอร์ที่ส่งกลับโดย Shapes() — std::vector<std::unique_ptr<Shape>> — ซึ่งเติมเต็มโดยการสร้างรูปทรง, ตั้งค่ารูปทรงนั้น, และย้ายมันเข้าสู่เวกเตอร์นั้น เมือสร้างเสร็จ, Graph เองจะถูกวางบนหน้าโดยใช้ Page.Paragraphs().Add(), ซึ่งเป็นคอลเลกชันเดียวกับที่ใช้สำหรับเนื้อหาระดับหน้าต่างอื่น ๆ.
#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");วาดวงกลมและวงรี
Circle และ Ellipse แต่ละรายการแสดงเรขาคณิตเป็นคุณสมบัติตัวเลขธรรมดาแทนการใช้ประเภทจุดหรือสี่เหลี่ยมที่ใช้ร่วมกัน Circle คือจุดศูนย์กลางและรัศมี — PosX(), PosY(), Radius() — ในขณะที่ Ellipse คือกล่องขอบเขต — Left(), Bottom(), Width(), Height(). ทั้งสองสืบทอด CheckBounds(containerWidth, containerHeight) จาก Shape, ซึ่งรายงานว่ารูปทรงปัจจุบันของเรขาคณิตนั้นพอดีภายในคอนเทนเนอร์ที่มีขนาดกำหนดหรือไม่โดยไม่ต้องเปลี่ยนแปลงรูปทรงเอง.
#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);วาดเส้นด้วย PositionArray
Line เก็บเรขาคณิตของมันแตกต่างจาก Circle และ Ellipse: PositionArray() จะคืนค่า std::vector<float> แบนที่เก็บคู่ x, y สำหรับทุกจุดที่เส้นผ่านไป, แทนที่จะเป็นชุดคุณสมบัติที่ตั้งชื่อไว้แบบคงที่. จุดสองจุด (สี่ค่า) วาดส่วนตรง; คู่เพิ่มเติมจะวาดเส้นหลายส่วนผ่านจุดเหล่านั้นตามลำดับ. เช่นเดียวกับรูปร่างอื่น ๆ, Line จะเขียนทับ CheckBounds(containerWidth, containerHeight) จาก 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);การจัดรูปแบบรูปร่างด้วย GraphInfo และ BorderInfo
แต่ละรูปร่างอ่านและเขียนสไตล์เส้นขอบและการเติมผ่าน Shape.GraphInfo() / GraphInfo(value). GraphInfo มีค่าเริ่มต้นเป็น LineWidth() ของ 1.0f พร้อมกับ DashArray() ว่าง, และยังเปิดเผย Color(), FillColor(), DashArray()/DashPhase() สำหรับเส้นประ, IsDoubled() สำหรับเส้นคู่, และ SkewAngleX()/SkewAngleY(), ScalingRateX()/ScalingRateY(), และ RotationAngle() สำหรับการแปลงเส้น. Graph เองมี BorderInfo, ตั้งค่าผ่าน Border(), ซึ่งจัดกลุ่ม GraphInfo หนึ่งรายการต่อขอบ — Left(), Right(), Top(), Bottom() — พร้อมกับ RoundedBorderRadius(), และสามารถสร้างได้โดยระบุขอบที่ต้องการสไตล์ด้วยแฟล็ก BorderSide (BorderSide::Left | BorderSide::Right, หรือ BorderSide::All สำหรับทุกขอบ).
#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);เคล็ดลับและแนวปฏิบัติที่ดีที่สุด
- เรียก
CheckBoundsกับWidth()/Height()ของGraphที่เป็นเจ้าของเอง, ไม่ใช่กล่องสื่อเต็มของหน้า — การตรวจสอบจะตรวจสอบเรขาคณิตของรูปร่างกับขนาดคอนเทนเนอร์ที่คุณส่งเข้าไป, ไม่ได้มองหน้าโดยอัตโนมัติ. - เพิ่มรูปร่างลงใน
Shapes()ก่อนเพิ่มGraphไปยังPage.Paragraphs()— การสร้างCircle,Ellipse, หรือLineจะไม่มีผลที่มองเห็นได้จนกว่าจะถูกเพิ่มต่อท้ายไปยังGraphของเจ้าของและGraphนั้นถูกเพิ่มไปยังหน้า. - จัดกลุ่มรูปร่างที่เกี่ยวข้องภายใต้
Graphเดียวแทนการใช้Graphหนึ่งรายการต่อรูปร่าง;Left()/Top()/Width()/Height()จะกำหนดตำแหน่งของคอนเทนเนอร์ทั้งหมดหนึ่งครั้ง, และรูปร่างทุกอันในShapes()จะถูกวาดสัมพันธ์กับมัน. - กำหนดค่า
Shape.GraphInfo()อย่างชัดเจนสำหรับรูปร่างที่ต้องการการเติมที่มองเห็นได้หรือเส้นขอบที่ไม่ใช่ค่าเริ่มต้น — ค่าเริ่มต้นของGraphInfoมีความกว้างเส้น1.0f, ไม่มีการเติม, และDashArray()ว่าง. - สร้าง
Line.PositionArray()เป็นคู่x0, y0, x1, y1, …ตามลำดับที่เส้นทางควรจะวาด — เวกเตอร์ที่มีความยาวคี่บรรยายจุดที่ไม่สมบูรณ์.
ปัญหาทั่วไป
| ปัญหา | สาเหตุ | วิธีแก้ |
|---|---|---|
ไม่มี Circle, Ellipse หรือ Line ปรากฏบนหน้าที่บันทึกไว้ | รูปร่างถูกสร้างขึ้นแต่ไม่เคยถูกต่อเข้ากับ Graph’s Shapes() ของมัน, หรือ Graph ไม่เคยถูกเพิ่มลงในหน้า | ผลักรูปร่างไปยัง graph->Shapes() แล้วเรียก page.Paragraphs().Add(graph) |
| รูปร่างถูกวาดด้วยเส้นสีดำบางค่าเริ่มต้น | Shape.GraphInfo() ไม่เคยถูกตั้งค่า | เรียก shape->GraphInfo(customGraphInfo) ก่อนเพิ่มรูปทรงไปยัง Shapes() |
Line ขาดหายไปหรือดูเหมือนจุดเดียว | PositionArray() มีน้อยกว่าคู่ (x, y) สองคู่ หรือมีจำนวนค่าที่เป็นเลขคี่ | จัดให้มีค่าต่ำสุดสี่ค่าเป็น x0, y0, x1, y1 |
| มีการจัดรูปแบบเฉพาะบางขอบของกรอบคอนเทนเนอร์เท่านั้น | BorderInfo ถูกสร้างด้วยมาสก์ BorderSide ที่ตัดบางขอบออก | ใช้ BorderSide::All หรือทำ OR รวมทุกแฟล็ก BorderSide ที่จำเป็น |
CheckBounds กลับค่าที่ไม่คาดคิดเป็น false | มิติที่ส่งให้ CheckBounds ไม่ตรงกับคอนเทนเนอร์ที่รูปทรงถูกวาดจริง | ส่งค่า Width()/Height() ปัจจุบันของ Graph ที่เป็นเจ้าของ |
FAQ
ความแตกต่างระหว่าง Circle กับ AnnotationType::Circle คืออะไร?
Circle (คู่มือนี้) เป็นรูปแบบการวาดที่วาดโดยตรงลงในเนื้อหาหน้าเว็บผ่าน Graph AnnotationType::Circle และ CircleAnnotation เป็นส่วนของ API ที่แยกออกจากกันและเป็นการทำเครื่องหมายรูปวงกลมแทน — ทั้งสองไม่มีความเกี่ยวข้องกันแม้ว่าจะใช้ชื่อเดียวกัน.
กราฟเดียวสามารถมีรูปทรงมากกว่าหนึ่งรูปได้หรือไม่?
ใช่. Graph.Shapes() คืนค่า std::vector<std::unique_ptr<Shape>> เต็มรูปแบบสำหรับคอนเทนเนอร์นั้น, และการผสมผสานใด ๆ ของอินสแตนซ์ Circle, Ellipse และ Line สามารถเพิ่มต่อท้ายได้ก่อนที่ Graph จะถูกเพิ่มลงในหน้า.
Circle และ Ellipse แบ่งปันประเภทเรขาคณิตเดียวกันหรือไม่?
No. Circle เป็นจุดศูนย์กลางและรัศมี (PosX, PosY, Radius); Ellipse เป็นกล่องขอบเขต (Left, Bottom, Width, Height). ทั้งสองสืบทอดจาก Shape แต่ไม่มีอันใดอันหนึ่งที่มีจุดหรือประเภทสี่เหลี่ยมร่วมกันกับอีกอัน.
การวาดรูปทรงด้วย Graph เป็นเช่นเดียวกับการเรนเดอร์หน้าเป็นภาพหรือไม่?
No. Graph, Shape, Circle, Ellipse และ Line สร้างเรขาคณิตเวกเตอร์ใหม่ลงในเนื้อหาของหน้าในระหว่างที่สร้างเอกสาร การแปลงหน้าที่มีอยู่เป็นภาพเรสเตอร์เป็นความสามารถแยกต่างหาก ซึ่งจัดการโดย BmpDevice, JpegDevice และ TiffDevice.
ฟังก์ชัน GraphInfo.IsDoubled() ทำอะไร?
มันทำเครื่องหมายให้ stroke เป็นเส้นคู่แทนการเปลี่ยนคุณสมบัติ stroke อื่น ๆ มันเป็นแฟล็กบูลีนที่อ่านและตั้งค่าผ่าน IsDoubled() / IsDoubled(value) ร่วมกับคุณสมบัติ stroke อื่น ๆ GraphInfo.
API Reference สรุป
| คลาส/เมธอด | คำอธิบาย |
|---|---|
Graph | คอนเทนเนอร์รูปทรงที่วางบนหน้า; กำหนดตำแหน่งของตนเองด้วย Left(), Top(), Width(), Height() |
Graph.Shapes() | คืนค่า std::vector<std::unique_ptr<Shape>> ที่คอนเทนเนอร์นี้วาด |
Graph.GraphInfo() / GraphInfo(value) | รับ/ตั้งค่าการจัดรูปแบบเส้นขอบและการเติมของคอนเทนเนอร์เอง |
Graph.Border() / Border(value) | รับ/ตั้งค่า BorderInfo ที่เป็นกรอบของคอนเทนเนอร์ |
Shape | ฐานเชิงนามธรรมสำหรับ Circle, Ellipse และ Line; เปิดเผย GraphInfo() และ CheckBounds() |
Shape.CheckBounds(w, h) | รายงานว่ารูปร่างของเรขาคณิตนั้นพอดีภายในคอนเทนเนอร์ที่มีความกว้าง/ความสูงตามที่กำหนดหรือไม่ |
Circle | รูปทรงวงกลม: PosX(), PosY(), Radius() |
Ellipse | รูปทรงวงรี: กล่องขอบเขตผ่าน Left(), Bottom(), Width(), Height() |
Line | รูปทรงเส้น/เส้นทาง: PositionArray(), std::vector<float> แบนของพิกัด x, y |
GraphInfo | การจัดรูปแบบเส้น/เติม: LineWidth(), Color(), FillColor(), DashArray(), DashPhase(), IsDoubled(), RotationAngle(), SkewAngleX()/SkewAngleY(), ScalingRateX()/ScalingRateY() |
BorderInfo | ขอบคอนเทนเนอร์ต่อด้าน: Left(), Right(), Top(), Bottom() (แต่ละเป็น GraphInfo) รวมกับ RoundedBorderRadius() |
BorderSide | Enum ที่เลือกขอบเมื่อสร้าง BorderInfo: None, Left, Top, Right, Bottom, All, Box |