应用于两个不同 PDF 的相同图像操作,不同的结果

Same image operations applied to two different PDFs, different results

我正在处理两个不同的 PDF,但要对它们应用相同的操作。

我正在处理一些初步代码,使用 Aspose 使用完全相同的代码将相同的图像应用于两个 PDF 文件。我不想立即责怪库,因为它能够在处理 Office 365 文档时生成正确的输出:

// note: Anyone familiar with the PDF format itself should have no 
//       issues inferring the low-level operations being performed here...

fun Page.writeImage(image: InputStream) {

    val imageName = resources.images.add(image.inMemory());

    val rectangle = rectangleFromTopLeft(0.0, 0.0, 400.0, 200.0);
    val matrix = rectangle.defaultMatrix();

    contents.add(listOf(
        GSave(),
        ConcatenateMatrix(matrix),
        Do(imageName),
        GRestore()
    ));
}

无论我提供哪个文件,这两种情况下矩形和矩阵的坐标都保持不变。

对于 Office 365 派生的 PDF,图像会按照我指定的方式应用于页面。奇怪的是,当我打开 Google Docs 派生的 PDF 时,应用的图像垂直翻转并位于页面底部!

View the four PDF files in their before and after states.

我希望任何 PDF 专家能够向我解释这里发生了什么。我最初怀疑 Google Docs PDF 中的某些先前状态或操作在我的图像操作之前生效。

就是说,我对 PDF 规范还不够熟悉(还!),无法挑选出来...

我不知道你应该责怪谁,但造成这种差异的原因很简单。

Google Docs 文档有一个以以下内容开头的页面流:

1 0 0 -1 0 792 cm

这基本上是页面的垂直翻转,792 是为了补偿并向后移动页面上的内容 - 它应该是页面的高度(以磅为单位)。

它没有将其封装在 q ... Q 对中以执行“保存...恢复”,这意味着现在已为页面上所有后续内容的其余部分设置此矩阵。您可能已经知道,PDF 规范没有提供重置页面矩阵的方法,您只能附加到它。

当您在页面末尾添加内容时,您的内容现在会继承此矩阵,这就是您看到它翻转并位于底部的原因。

Microsoft 文件没有这样做,因此处理得当。在这种情况下,矩阵仍然是单位矩阵,您最终会得到您期望的内容。

如何解决这个问题?好吧,如果您的图书馆不提供了解当前页面矩阵是什么的方法,那将非常困难。它当然可以通过应用逆矩阵来抵消 Google 在这里所做的愚蠢的事情来“仅针对此文档”来解决,但我可以想象这不是您正在寻找的处理这个问题的最终方法.