C++에서 PDF 그래픽 작업하기
Aspose.PDF FOSS for C++에는 PDF 페이지에 자유형 형태를 직접 그릴 수 있는 작은 벡터 그래픽 API가 포함되어 있습니다 — 라이브러리의 래스터 렌더링 장치(BmpDevice, JpegDevice, TiffDevice)와는 별도로, 기존 페이지 콘텐츠를 이미지로 변환합니다. 이 가이드는 Graph 컨테이너를 만들고, Circle, Ellipse, Line 형태를 추가하며, GraphInfo로 해당 형태들을 스타일링하고, 완성된 Graph를 페이지에 배치하는 과정을 안내합니다. 라이브러리는 CMake를 통해 프로젝트에 추가됩니다.
단계별 가이드
Step 1: 패키지 설치
라이브러리를 CMake 서브디렉터리로 추가하고 aspose_pdf_foss 타깃에 링크합니다:
add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)툴체인과 헤더가 해결되는지 최소 프로그램을 컴파일하여 확인합니다:
#include <aspose/pdf/document.hpp>
#include <iostream>
int main() {
Aspose::Pdf::Document doc;
std::cout << "Linked OK — pages: " << doc.Pages().Count() << "\n";
}pages: 0 를 출력하는 성공적인 빌드는 라이브러리가 올바르게 링크되었음을 확인시켜 줍니다.
2단계: 필요한 클래스 가져오기
문서, 도형 컨테이너, 세 개의 구체적인 도형 및 해당 스타일 유형에 대한 헤더를 포함합니다:
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/drawing/graph.hpp>
#include <aspose/pdf/drawing/circle.hpp>
#include <aspose/pdf/drawing/ellipse.hpp>
#include <aspose/pdf/drawing/line.hpp>
#include <aspose/pdf/graph_info.hpp>
#include <aspose/pdf/border_info.hpp>
#include <aspose/pdf/color.hpp>
using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Drawing;Graph, Shape, Circle, Ellipse, 및 Line는 Aspose::Pdf::Drawing 네임스페이스에 존재합니다; GraphInfo, BorderInfo, 그리고 Color는 Aspose::Pdf 바로 아래에 존재합니다.
3단계: 그래프를 생성하고 페이지에 추가하기
Graph는 Left(), Top(), Width(), Height()를 통해 페이지 상에 위치를 잡는 컨테이너이며, Shapes()를 통해 내부에 그려진 도형들을 보관합니다. 구성된 후에는 다른 페이지 콘텐츠와 동일한 컬렉션인 Page.Paragraphs().Add()을 통해 페이지에 배치됩니다:
Document doc;
Page page = doc.Pages().Add();
auto graph = std::make_shared<Graph>();
graph->Left(50.0);
graph->Top(50.0);
graph->Width(400.0);
graph->Height(400.0);
page.Paragraphs().Add(graph);4단계: 원과 타원을 그리기
Circle는 PosX(), PosY(), Radius()을 사용하여 기하학을 설명합니다. Ellipse는 대신 경계 상자를 사용합니다 — Left(), Bottom(), Width(), Height(). 두 도형 모두 Shapes()가 반환하는 벡터에 Shape 포인터로 추가하여 Graph에 삽입됩니다:
auto circle = std::make_unique<Circle>();
circle->PosX(150.0);
circle->PosY(150.0);
circle->Radius(75.0);
graph->Shapes().push_back(std::move(circle));
auto ellipse = std::make_unique<Ellipse>();
ellipse->Left(20.0);
ellipse->Bottom(20.0);
ellipse->Width(120.0);
ellipse->Height(60.0);
graph->Shapes().push_back(std::move(ellipse));두 도형 모두 Shape로부터 CheckBounds(containerWidth, containerHeight)를 상속받으며, 이는 도형의 현재 기하학이 주어진 크기의 컨테이너 안에 들어가는지 여부를 보고합니다:
bool circleFits = circle->CheckBounds(graph->Width(), graph->Height());5단계: 선 그리기
Line는 기하 정보를 다르게 저장합니다: PositionArray()는 좌표의 평면 std::vector<float>를 보유합니다 — 점당 x, y 쌍 — 명명된 속성이 아니라. 두 점 세그먼트는 네 개의 값이 필요합니다: 시작 x, 시작 y, 끝 x, 끝 y.
auto line = std::make_unique<Line>();
line->PositionArray({0.0f, 0.0f, 400.0f, 400.0f});
graph->Shapes().push_back(std::move(line));6단계: GraphInfo와 컨테이너 테두리로 도형 스타일 지정
각 도형의 스트로크와 채우기는 GraphInfo에서 가져오며, Shape.GraphInfo() / GraphInfo(value)를 통해 읽고 설정합니다. 여기서는 스트로크 두께 (LineWidth(), 기본값 1.0f), 스트로크 및 채우기 색상 (Color(), FillColor()), 그리고 대시 패턴 (DashArray(), DashPhase())을 노출합니다:
GraphInfo stroke;
stroke.LineWidth(2.0f);
stroke.Color(Color::FromRgb(1.0, 0.0, 0.0));
stroke.FillColor(Color::FromRgb(1.0, 0.9, 0.9));Graph 컨테이너 자체는 BorderInfo을 가지고 있으며, Border()를 통해 설정합니다. 이는 각 가장자리마다 하나의 GraphInfo을 그룹화합니다 (Left(), Right(), Top(), Bottom()) 그리고 컨테이너 자체 프레임을 위한 RoundedBorderRadius()을 추가합니다:
BorderInfo border{BorderSide::All, 1.5f, Color::Black()};
border.RoundedBorderRadius(6.0);
graph->Border(border);7단계: 문서 저장
doc.Save("graphics.pdf");일반적인 문제 및 해결 방법
내가 만든 도형이 페이지에 절대 나타나지 않음
단독으로 Circle, Ellipse, 또는 Line를 생성해도, 해당 객체가 소유자 Graph의 Shapes()가 반환하는 벡터에 추가되고, 그 Graph가 Page.Paragraphs().Add()을 통해 페이지에 추가될 때까지 효과가 없습니다. 세 단계—생성, 추가, Graph을 페이지에 추가—가 모두 필요합니다.
도형이 잘못된 위치에 렌더링됩니다
Graph.Left()와 Graph.Top()은 페이지에 컨테이너를 배치합니다; 도형 속성(Circle.PosX()/PosY(), Ellipse.Left()/Bottom(), Line.PositionArray() 좌표)은 해당 컨테이너 내의 기하학을 설명합니다. 출력이 어긋난 것처럼 보일 때는 컨테이너 배치와 도형 자체 좌표를 모두 확인하십시오.
CheckBounds returns false unexpectedly
CheckBounds(containerWidth, containerHeight)는 전달된 치수와 도형 자체의 기하학을 비교합니다 — 일반적으로 페이지 전체 미디어 박스가 아니라 소유자 Graph의 Width()/Height()을 사용합니다. 잘못된 치수를 전달하면 도형이 실제로 Graph 안에 들어갈 수 있음에도 불구하고 false negative가 발생합니다.
A Line 표시되지 않거나, 단일 점으로 표시됩니다
PositionArray()는 가시적인 구간을 설명하기 위해 최소 두 개의 (x, y) 쌍, 즉 네 개의 float 값이 필요합니다. 짧은 벡터는 선을 형성하지 못합니다.
Confusing Circle with AnnotationType::Circle or CircleAnnotation
이 라이브러리에는 별도의 PDF 주석 API도 있으며, 여기서 AnnotationType::Circle와 CircleAnnotation은 원형 마크업 주석을 나타냅니다. 이 가이드에서 다루는 Circle 클래스는 관련이 없으며 — Aspose::Pdf::Drawing에 존재하고 주석 객체를 추가하는 대신 페이지 콘텐츠에 직접 그립니다.
자주 묻는 질문
GraphInfo와 BorderInfo의 차이점은 무엇인가요?
GraphInfo은 단일 스트로크 — 선 두께, 색상, 채우기 색상, 대시 패턴 — 를 스타일링하며, 개별 도형(Shape.GraphInfo()을 통해)과 BorderInfo 내부의 각 가장자리 모두에 사용됩니다. BorderInfo은 네 가지 GraphInfo 값(Left(), Right(), Top(), Bottom())과 RoundedBorderRadius() 하나를 그룹화하여 Graph 컨테이너 자체의 테두리 프레임을 설명합니다.
도형을 단색으로 채울 수 있나요?
예. GraphInfo.FillColor()은 도형이 소유하고 있는 Graph을 통해 그려질 때 사용되는 채우기 색상을 설정합니다.
Circle은 Ellipse처럼 경계 상자를 저장하나요?
No. Circle은 PosX(), PosY(), Radius()을 공개합니다; Ellipse은 Left(), Bottom(), Width(), Height()을 공개합니다. 이들은 추상 Shape 기반 및 GraphInfo 스타일링을 제외하고는 공통된 기하학 표현을 공유하지 않습니다.
하나의 Graph가 둘 이상의 도형을 보유할 수 있나요?
예. Graph.Shapes()은 해당 Graph 내에 배치된 Shape 객체의 전체 컬렉션을 반환합니다 — 원, 타원 및 선을 모두 동일한 컨테이너에 추가할 수 있습니다.
페이지를 이미지로 렌더링하는 것과 동일한가요?
아니요. BmpDevice, JpegDevice, TiffDevice는 기존 페이지 콘텐츠를 이미지 형식으로 래스터화합니다. Graph, Shape, Circle, Ellipse, Line는 문서가 생성되거나 편집되는 동안 PDF 콘텐츠에 직접 새로운 벡터 기하학을 구성합니다.