pdflib - PHP:将具有背景颜色的 PDI 对象作为单个 object/group 插入

pdflib - PHP: Inserting PDI object with background color as a single object/group

目前正在使用较旧(和最新)版本的 pdflib(7.0 和 9.2)。我想要一个可能的解决方案来处理 7。我们有一个应用程序,我们可以从多个较小的 PDF 文件组成一个 PDF 文件。这些 PDF 文件可能没有明确的背景对象集,因此它们在插入时透明处于活动状态(即背景闪耀)。

使用PDI插入对象($p指父文档):

$pdf_doc = PDF_open_pdi_document($p, $file, "");
$image = PDF_open_pdi_page($p, $pdf_doc, 1, "");
PDF_fit_pdi_page($p, $image, $x, $y, $boxsize . " position 50 fitmethod meet");
PDF_close_pdi_page($p, $image);

只要背景符合预期(即白色),这就可以正常工作。在某些情况下,有人想要不同的背景(不同的 PDF 文件或不同的颜色),我们首先添加一个具有相同框大小的白框,然后在其上绘制 PDF 文档 - 有效地为单个文件创建白色背景插入的对象。

function draw_box($pdf, $offset_x, $offset_y, $width, $height) {
    PDF_setcolor($pdf, 'fill', 'cmyk', 0, 0, 0, 0);
    PDF_rect($pdf, $offset_x, $offset_y, $width, $height);
    PDF_fill($pdf);
}

这很适合观看。当有人想稍后在 Adob​​e Acrobat 或 Adob​​e Illustrator 中编辑生成的 PDF 时,问题就来了——作为背景绘制的框没有与其他 PDF 内容组合在一起,这使得它更难使用——你必须确保您也移动了插入的 PDF 文件后面的白框。

我想解决这个问题,而不必在所有源 PDF 中插入明确的背景对象,因为源 PDF 的数量太多,这不是一个真正可行的策略。

我已经尝试通过创建一个新的 PDF 文档、在该文档中绘制白框,然后再次将 PDF 插入到该文档中来解决该问题。这似乎需要将 pdf 写入磁盘然后加载它,出于性能原因我想避免这种情况。文档说可以使用 "virtual pdf file",但我无法在 pdflib 文档中找到对此的任何引用。当我尝试从内存中的 PDF 创建 PDI 文档时,下面的代码会出错。

$inserted = PDF_new();
PDF_begin_document($inserted, "", '');
$inserted_page = PDF_begin_page_ext($inserted, 20, 20, '');

$pdf_doc = PDF_open_pdi_document($inserted, $file, "");
$image = PDF_open_pdi_page($inserted, $pdf_doc, 1, "");
PDF_fit_pdi_page($inserted, $image, $x, $y, $boxsize . " position 50 fitmethod meet");
PDF_close_pdi_page($inserted, $image);

// then create a PDI document to insert into the parent
// This barfs, since it expects a file.
$new = PDF_open_pdi_document($p, $inserted, "");

我也尝试过直接绘制到 PDI 文档,但这导致了分段错误。遗憾的是,我再也没有该尝试的代码了。

那么对于如何通过 PDI 在插入的 PDF 中获得白色背景颜色作为默认颜色,或者将绘制的框与 PDI 插入的对象合并,有什么建议的解决方案吗?

主要问题如下:

This works fine for viewing. The problem comes when someone wants to edit the resulting PDF later in Adobe Acrobat or Adobe Illustrator - the box that has been drawn as the background is not grouped together with the rest of the PDF content, making it harder to work with - you have to make sure you're also moving the white box behind the inserted PDF file

由于 PDF 是最终格式,因此不适合以后编辑。因此没有 "groupings" 或其他逻辑编辑信息可用。

因此,处理 PDF 文件永远不会像您拥有专为它设计的文档格式那样可靠地工作。

因此是否将PDF元素识别为一个组取决于应用程序。使用当前的 Acrobat DC 版本时,我无法将整个导入的页面作为单个对象移动。它为我提供了几个较小的对象来移动。

=> 我不建议编辑 PDF 文件。

但是根据您的描述,您使用的 Acrobat/Illustrator 版本似乎将 XObject 视为可以移动的单个对象。如果这个假设是正确的,您可以将白色矩形和 PDI 页面封装在一个模板中。 此解决方法可能适用于您当前的版本,但可能不适用于更高版本。

有关此功能的详细介绍,请参阅 PDFlib 9.2 教程,第 3.2.4 章“Templates (Form XObjects)”,其用法也在 "repeated content" PDFlib Cookbook 中的示例。模板在过时的 PDFlib 7 中也可用,但在过去十年中得到了扩展。

关于 PVF:PDFlib 7 和 9 下载包中包含的 starter_pvf 示例演示了 PVF 的使用。 (在 PDFlib 说明书 "starter_pvf" 中可用) 在您的情况下,您应该在内存中创建第一个文档并使用 get_buffer() 检索数据。对于新文档,使用新名称和 get_buffer() 的内容创建一个新的 PVF 文件。然后用 open_pdi_document() 打开这个文件。在这种情况下,您的光盘上没有任何文件。

根据 Rainer 的上述回答,我最终得到了以下有效的结果 - 最终在 Illustrator 中得到了一个对象。 $pdf 是包含的 PDF:

function draw_box($pdf, $offset_x, $offset_y, $width, $height)
{
    PDF_setcolor($pdf, 'fill', 'cmyk', 0, 0, 0, 0);
    PDF_rect($pdf, $offset_x, $offset_y, $width, $height);
    PDF_fill($pdf);
}

function insert_pdf_file($pdf, $file, $offset_x, $offset_y, $page = 1)
{
    $src = PDF_open_pdi_document($pdf, $file, "");
    $page = PDF_open_pdi_page($pdf, $src, $page, "");

    // Insert PDF page into current PDF
    PDF_fit_pdi_page($pdf, $page, $offset_x, $offset_y, "");
}

function insert_pdf_file_with_background($pdf, $inserted, $offset_x, $offset_y, $width, $height)
{
    $grouped = PDF_begin_template_ext($pdf, $width, $height, '');
    draw_box($pdf, 0, 0, $width, $height);
    insert_pdf_file($pdf, $inserted, 0, 0);
    PDF_end_template($pdf);

    PDF_fit_image($pdf, $grouped, $offset_x, $offset_y, "");
}

对于 pdflib 7,我必须将 open_pdi_documentopen_pdi_page 移到模板上下文之外。结果还是符合预期。