跳转到内容

绘制渐变,并使用透明度与混合模式

使用由两个端点定义的轴向(线性)或放射状渐变填充区域,再用固定 alpha 与可选的混合模式合成彼此重叠的形状。示例代码遵循 examples/25-gradients.phpexamples/20-transparency.php

渐变是一种 ISO 32000-2 shading(着色)。linearGradient() 会生成 Type 2(轴向)shading,而 radialGradient() 会生成 Type 3(放射状)shading。透明度则由图形状态中的 alpha 常量控制。setAlpha() 会设置非描边的 ca 值与描边的 CA 值。

Terminal window
composer require nextpdf/core:^3

不需要任何可选扩展。渐变、alpha 与混合模式 API 自 1.0.0 起保持稳定,并可在 8.1–8.4 的向后移植矩阵上运行。

linearGradient(x, y, w, h, start, end) 会沿着方框轴线,在两个 Color 端点之间绘制颜色渐变。ISO 32000-2 将轴向 shading 的 Coords 定义为 [x0 y0 x1 y1]。如果两个端点重合,则不会绘制任何内容。radialGradient(...) 会在两个圆之间生成渐变。放射状 Coords[x0 y0 r0 x1 y1 r1],且两个半径都必须 ≥ 0。

setAlpha($alpha, $mode) 会为后续绘制设置固定不透明度。第一个参数是 alpha 常量(ca/CA)。第二个参数会选定混合模式(在透明成像模型中即 BM)。在绘制不相关内容之前,先将 alpha 重置为 1.0,并将混合模式重置为 Normal

此 API 接口由 PHPDoc 自动生成。本示例会用到以下方法:

  • linearGradient(float $x, float $y, float $w, float $h, Color $start, Color $end): static
  • radialGradient(float $x, float $y, float $w, float $h, Color $start, Color $end): static
  • setAlpha(float $alpha, BlendMode $mode = BlendMode::Normal): static
  • Color::rgb(int $r, int $g, int $b)Color::white()Color::black() 提供渐变颜色端点。
  • setFillColor(...) 会设置用于 alpha 与混合模式合成的颜色。
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
use NextPDF\Graphics\BlendMode;
use NextPDF\Graphics\Color;
$doc = Document::createStandalone();
$doc->addPage();
// Axial gradient: blue -> white across a 190 x 40 box.
$doc->linearGradient(10, 30, 190, 40, Color::rgb(30, 58, 138), Color::white());
// Two overlapping rectangles at 70% opacity with Multiply blend.
$doc->setAlpha(0.7, BlendMode::Multiply);
$doc->setFillColor(220, 38, 38);
$doc->rect(20, 90, 60, 40, 'F');
$doc->setFillColor(37, 99, 235);
$doc->rect(50, 90, 60, 40, 'F');
$doc->setAlpha(1.0, BlendMode::Normal); // reset
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/gradients.pdf');

这是一个完整示例,可直接用于测试框架。它会遵循 NEXTPDF_COOKBOOK_OUTPUT,且不会自行固定任何熵。

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
use NextPDF\Graphics\BlendMode;
use NextPDF\Graphics\Color;
$doc = Document::createStandalone();
$doc->setTitle('Gradients and Transparency');
$doc->addPage();
$doc->setFont('helvetica', 'B', 18);
$doc->cell(0, 12, 'Gradients and Transparency', newLine: true);
$doc->ln(4);
// 1. Axial gradient — blue to white.
$doc->setFont('helvetica', 'B', 12);
$doc->cell(0, 8, '1. Axial gradient', newLine: true);
$doc->ln(2);
$doc->linearGradient(
x: 10, y: $doc->getY(), w: 190, h: 40,
start: Color::rgb(30, 58, 138), end: Color::white(),
);
$doc->ln(44);
// 2. Radial gradient — red centre fading to white.
$doc->setFont('helvetica', 'B', 12);
$doc->cell(0, 8, '2. Radial gradient', newLine: true);
$doc->ln(2);
$doc->radialGradient(
x: 50, y: $doc->getY(), w: 110, h: 55,
start: Color::rgb(220, 38, 38), end: Color::white(),
);
$doc->ln(59);
// 3. Constant alpha + blend mode over a light backdrop.
$doc->setFont('helvetica', 'B', 12);
$doc->cell(0, 8, '3. Alpha 0.7 with Multiply blend', newLine: true);
$doc->ln(2);
$baseY = $doc->getY();
$doc->setAlpha(1.0, BlendMode::Normal);
$doc->setFillColor(245, 245, 245);
$doc->rect(15, $baseY, 90, 40, 'F');
$doc->setAlpha(0.7, BlendMode::Multiply);
$doc->setFillColor(220, 38, 38);
$doc->rect(20, $baseY + 5, 40, 30, 'F');
$doc->setFillColor(37, 99, 235);
$doc->rect(40, $baseY + 5, 40, 30, 'F');
// Always reset compositing state before continuing.
$doc->setAlpha(1.0, BlendMode::Normal);
$doc->setFillColor(255);
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/gradients.pdf';
$doc->save($out);
echo "Created gradients.pdf\n";
  • 渐变端点重合时不会绘制任何内容。wh 使轴线坍缩成零尺寸的方框时,依 ISO 32000-2 会产生空的轴向 shading。请确认方框具有实际范围。
  • 半径必须为非负值。 传入 radialGradient() 的负半径无效。两个半径皆为零时不会绘制任何内容。
  • Alpha 会在多次绘制之间持续生效。 setAlpha(0.7, …) 会对后续每一次绘制持续生效,直到你将其重置为止。在一段透明区块之后,请还原为 setAlpha(1.0, BlendMode::Normal),否则后续内容会显得褪色。
  • 混合模式需要有底图。 Multiply 或 Screen 这类混合模式会与已绘制的内容进行合成。在空白页面上,其效果不可见,因此请先绘制一块底图。
  • PDF 2.0 的混合模式数组已弃用。 NextPDF 会输出单一的混合模式名称,也就是 PDF 2.0 的形式。旧式数组形式在规范中已弃用。

一个渐变就是一个 shading 对象加一次填色。Alpha 与混合模式则是图形状态参数。每次使用的成本都是固定的,且两者都在 2000 ms / 64 MB 的预算范围之内。过程中不会发生栅格化,因此渐变仍是不受输出尺寸影响的矢量式 shading。

本示例只会绘制你的代码提供的几何图形与颜色。过程中不会发生任何输入解析或网络访问。对于来自不受信任数据的颜色与坐标值,请在使用前先进行验证。

陈述规范条款参考 ID
ShadingType 2 为轴向,3 为放射状。ISO 32000-2§8.7.4.3
轴向 Coords[x0 y0 x1 y1];端点重合时不会绘制任何内容。ISO 32000-2§8.7.4.5.3
放射状 Coords[x0 y0 r0 x1 y1 r1];半径 ≥ 0。ISO 32000-2§8.7.4.5.4
CA/ca 是 stroking/non-stroking 的 alpha 常量。ISO 32000-2§8.4.5
BM 是当前的混合模式。ISO 32000-2§11.3.5

可重现性配置 — 结构层级。 每次保存时,trailer 的 /ID 与日期原子都会不同。测试框架会移除这些原子,再比对经 qpdf 规范化后的结构。本示例说明 NextPDF 如何产生这个结构。它并未对 ISO 32000-2 符合性做出全面声明。

不适用。渐变、alpha 与混合模式都是核心功能。它们没有任何 Premium gate(付费门槛)。