Bỏ qua để đến nội dung

Vẽ đồ họa vector — hình khối, màu sắc và kiểu đường nét

Dùng công thức này để vẽ các hình cơ bản ở dạng tô đầy hoặc dạng viền: hình chữ nhật, hình chữ nhật bo góc, hình tròn, hình elip và đường thẳng. Với từng hình, bạn thiết lập màu tô, màu nét và độ rộng nét vẽ. Công thức này dựa theo examples/06-colors-and-drawing.php.

Mỗi hình cơ bản ánh xạ tới một đối tượng đường dẫn (path object) theo ISO 32000-2. Đối tượng đường dẫn là một hình dạng được tạo từ các đoạn thẳng và đoạn cong. Nó kết thúc bằng một toán tử vẽ (painting operator) để trình xem biết cần tô nét, tô đầy hay thực hiện cả hai.

Terminal window
composer require nextpdf/core:^3

Bạn không cần bất kỳ phần mở rộng tùy chọn nào. Giao diện lập trình ứng dụng (API) cho phần vẽ và màu sắc đã ổn định kể từ 1.0.0 và chạy trên ma trận backport 8.1–8.4.

Thiết lập trạng thái rồi vẽ. setFillColor(), setDrawColor()setLineWidth() cập nhật trạng thái đồ họa. Lần gọi rect(), circle(), ellipse(), roundedRect() hoặc line() tiếp theo sẽ dùng trạng thái đó. Các phương thức vẽ hình nhận một đối số chỉ kiểu vẽ: 'F' tô đầy, 'S' tô nét (giá trị mặc định), còn 'DF'/'FD' làm cả hai. Ở bên trong, một hình chữ nhật được tô đầy được biểu diễn bằng toán tử dựng đường dẫn re, theo sau là toán tử vẽ tô đầy. ISO 32000-2 §8.5.3 quy định S để tô nét và f để tô đầy; đây là các toán tử vẽ đường dẫn chính.

Màu sắc dùng màu thiết bị (device colour). setFillColor(r, g, b) chọn DeviceRGB. ISO 32000-2 §8.6.4.3 định nghĩa rg là toán tử màu không tô nét của DeviceRGB và g là toán tử tương đương cho DeviceGray. setFillColor($v) khi nhận một đối số sẽ đặt một mức xám. Độ rộng nét vẽ mặc định là 1.0, và mẫu nét đứt mặc định là đường liền (§8.4.3.6).

Bề mặt API được tạo từ PHPDoc. Công thức này sử dụng các phương thức sau:

  • rect(float $x, float $y, float $w, float $h, string $style = 'S'): static
  • roundedRect(float $x, float $y, float $w, float $h, float $r, string $style = 'S'): static
  • circle(float $x, float $y, float $r, string $style = 'S'): static
  • ellipse(float $x, float $y, float $rx, float $ry, string $style = 'S'): static
  • line(float $x1, float $y1, float $x2, float $y2): static
  • setFillColor(int $r, int $g = -1, int $b = -1): static / setDrawColor(...)
  • setLineWidth(float $width): static
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->addPage();
$doc->setFillColor(30, 58, 138);
$doc->rect(20, 30, 60, 40, 'F'); // filled rectangle
$doc->setDrawColor(217, 119, 6);
$doc->setLineWidth(1.0);
$doc->circle(140, 50, 20, 'S'); // stroked circle
$doc->setLineWidth(0.3);
$doc->line(20, 90, 190, 90); // thin rule
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/vector.pdf');

Ví dụ hoàn chỉnh này, sẵn sàng cho bộ kiểm thử, tôn trọng NEXTPDF_COOKBOOK_OUTPUT và không tự thêm bất kỳ phần ngẫu nhiên nào.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Colors and Drawing');
$doc->addPage();
$doc->setFont('helvetica', 'B', 18);
$doc->cell(0, 12, 'Colors and Drawing', newLine: true);
$doc->ln(5);
// --- Filled rectangles: set fill colour, then draw with style 'F' ---
$palette = [
[30, 58, 138], [217, 119, 6], [30, 27, 75],
[239, 66, 35], [21, 128, 61],
];
$x = 15.0;
$rowY = $doc->getY();
foreach ($palette as [$r, $g, $b]) {
$doc->setFillColor($r, $g, $b);
$doc->rect($x, $rowY, 30, 20, 'F');
$x += 35.0;
}
$doc->ln(28);
// --- Outlined shapes: set draw colour + line width, draw with 'S' ---
$doc->setDrawColor(30, 58, 138);
$doc->setLineWidth(0.5);
$y = $doc->getY();
$doc->rect(15, $y, 30, 25, 'S');
$doc->roundedRect(55, $y, 30, 25, 5, 'S');
$doc->circle(110, $y + 12.5, 12.5, 'S');
$doc->ellipse(150, $y + 12.5, 18, 10, 'S');
$doc->ln(33);
// --- Lines at three widths ---
$y = $doc->getY();
$doc->setDrawColor(0);
$doc->setLineWidth(0.2);
$doc->line(15, $y, 195, $y);
$doc->setLineWidth(0.8);
$doc->line(15, $y + 5, 195, $y + 5);
$doc->setLineWidth(1.5);
$doc->line(15, $y + 12, 195, $y + 12);
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/vector.pdf';
$doc->save($out);
echo "Created vector.pdf\n";

Trường hợp đặc biệt & điểm cần lưu ý

Phần tiêu đề “Trường hợp đặc biệt & điểm cần lưu ý”
  • Kiểu mặc định là tô nét. Nếu bạn bỏ qua đối số kiểu, hình sẽ được tô nét ('S'). Một hình có vẻ như không hiện thường là do nó được vẽ khi chưa đặt màu nét, hoặc được tô bằng màu nền của trang. Truyền 'F' để tô đầy hình đó.
  • Trạng thái màu được giữ lại. setFillColor() vẫn có hiệu lực cho đến khi bạn thay đổi. Hãy đặt lại, ví dụ với setFillColor(255), trước khối tiếp theo không liên quan; nếu không, màu sẽ bị mang theo.
  • Mức xám so với dạng nạp chồng RGB. setFillColor(128) là một mức xám. setFillColor(128, 0, 0) là RGB. Dạng một đối số không có nghĩa là “đỏ 128”.
  • Trục Y chạy từ trên xuống trong API. Các hàm trợ giúp vẽ lấy gốc tọa độ ở góc trên bên trái của tài liệu. Engine sẽ tự ánh xạ điều đó sang không gian người dùng PDF có gốc ở góc dưới bên trái.

Mỗi hình cơ bản chỉ tạo ra một số ít toán tử trong luồng nội dung. Hàng nghìn hình trên mỗi trang vẫn nằm gọn trong ngân sách 2000 ms / 64 MB. Chi phí tăng tuyến tính theo số lượng hình cơ bản. Không có quá trình raster hóa, nên đầu ra vẫn ở dạng vector.

Công thức này chỉ vẽ hình học mà mã của bạn chỉ định. Nó không phân tích bất kỳ đầu vào nào và không truy cập mạng. Hãy kiểm tra phạm vi của mọi tọa độ đến từ dữ liệu không đáng tin cậy. Việc kiểm tra này ngăn một giá trị độc hại đẩy các nét vẽ ra xa ngoài phạm vi trang.

Phát biểuĐặc tảĐiều khoảnreference_id
Đối tượng đường dẫn là các đường thẳng, hình chữ nhật và đường cong Bézier kết thúc bằng một toán tử vẽ.ISO 32000-2§8.5
S tô nét và f tô đầy một đường dẫn.ISO 32000-2§8.5.3
rg đặt màu không tô nét của DeviceRGB; g đặt DeviceGray.ISO 32000-2§8.6.4.3
Giá trị khởi tạo của mẫu nét đứt là [] 0, tức một đường liền.ISO 32000-2§8.4.3.6

Hồ sơ khả năng tái lập — dạng cấu trúc. Việc vẽ vector không tự có phần ngẫu nhiên nào. Dù vậy, mỗi tài liệu được lưu đều mang theo một /ID trong trailer và các nguyên tử ngày tháng. ISO 32000-2 §8.3.4 cũng nêu rằng cách sắp xếp chính xác của các toán tử trạng thái đồ họa không mang ý nghĩa ngữ nghĩa, nên một bộ chuẩn hóa có thể sắp xếp lại trạng thái tương đương. Tuyên bố được hỗ trợ là sự tương đương về cấu trúc sau khi chuẩn hóa bằng qpdf. Công thức này mô tả cách NextPDF tạo ra cấu trúc đó. Nó không khẳng định tính tuân thủ ISO 32000-2 như một tuyên bố bao trùm.

Không áp dụng. Vẽ vector là một khả năng của Core và không nằm sau rào chắn Premium.