PDFBox 叠加失败

2024-03-02

我使用 PDFBox 1.8.8 并尝试使用以下 scala 方法将 PDDocument 与其他文档叠加

def mergeTest() = {
val home = System.getProperty("user.home")
val doc = PDDocument.load(home + "/tmp/document.pdf")
val ovl = PDDocument.load(home + "/tmp/overlay.pdf")
val ov = new Overlay()
val mergeDoc = ov.overlay(ovl, doc)
mergeDoc.save(home + "/tmp/result.pdf")
doc.close()
ovl.close()
mergeDoc.close()

}

我期望将“document.pdf”(N页)的每一页都覆盖“overlay.pdf”(1页)的内容。

结果,“result.pdf”中的页面与“document.pdf”中的页面一样多,但是“document.pdf”的原始内容完全被覆盖内容覆盖。


原因

OP的覆盖.pdf https://dl.dropboxusercontent.com/u/21842502/picas/overlay.pdf页面内容开头为

/Cs1 cs
1 sc
0.1400146 841.945 m
595.14 841.945 l
595.14 -0.05499268 l
0.1400146 -0.05499268 l
h
f
0.1400146 841.945 m
595.14 841.945 l
595.14 -0.05499268 l
0.1400146 -0.05499268 l
h
f

这些操作绘制两个白色(CS1是一个灰度颜色空间)矩形几乎覆盖了整个MediaBox [0, 0, 595.28, 841.89]除了顶部和左侧的一条非常细的线之外

因此,将此页面内容放置在另一个页面上,完全覆盖了该其他页面的所有现有内容,这正是您所观察到的:

“document.pdf”的原始内容被覆盖内容完全覆盖

通常只有覆盖一个不能覆盖所有内容的页面才有意义。

使用混合模式的解决方法Darken

或者,您可能想尝试使用混合模式进行叠加Darken which 选择背景颜色和源颜色中较暗的一个, 背景被替换为光源,其中光源较暗;否则,它保持不变。

在Java中(我没有使用Scala的经验,所以我希望你可以利用Java源代码)你可以使用如下方法:

void overlayWithDarkenBlendMode(PDDocument document, PDDocument overlay) throws IOException
{
    PDXObjectForm xobject = importAsXObject(document, (PDPage) overlay.getDocumentCatalog().getAllPages().get(0));
    PDExtendedGraphicsState darken = new PDExtendedGraphicsState();
    darken.getCOSDictionary().setName("BM", "Darken");

    List<PDPage> pages = document.getDocumentCatalog().getAllPages();

    for (PDPage page: pages)
    {
        Map<String, PDExtendedGraphicsState> states = page.getResources().getGraphicsStates();
        if (states == null)
            states = new HashMap<String, PDExtendedGraphicsState>();
        String darkenKey = MapUtil.getNextUniqueKey(states, "Dkn");
        states.put(darkenKey, darken);
        page.getResources().setGraphicsStates(states);

        PDPageContentStream stream = new PDPageContentStream(document, page, true, false, true);
        stream.appendRawCommands(String.format("/%s gs ", darkenKey));
        stream.drawXObject(xobject, 0, 0, 1, 1);
        stream.close();
    }
}

PDXObjectForm importAsXObject(PDDocument target, PDPage page) throws IOException
{
    final PDStream xobjectStream = new PDStream(target, page.getContents().createInputStream(), false);
    final PDXObjectForm xobject = new PDXObjectForm(xobjectStream);

    xobject.setResources(page.findResources());
    xobject.setBBox(page.findCropBox());

    COSDictionary group = new COSDictionary();
    group.setName("S", "Transparency");
    group.setBoolean(COSName.getPDFName("K"), true);
    xobject.getCOSStream().setItem(COSName.getPDFName("Group"), group);

    return xobject;
}

(OverlayWithEffect.java https://github.com/mkl-public/testarea-pdfbox1/blob/master/src/test/java/mkl/testarea/pdfbox1/assembly/OverlayWithEffect.java)

将它们应用到您的示例文档中

@Test
public void testOverlayWithDarkenVolker() throws COSVisitorException, IOException
{
    try (   InputStream sourceStream = getClass().getResourceAsStream("document1.pdf");
            InputStream overlayStream = getClass().getResourceAsStream("overlay.pdf")  )
    {
        final PDDocument document = PDDocument.load(sourceStream);
        final PDDocument overlay = PDDocument.load(overlayStream);

        overlayWithDarkenBlendMode(document, overlay);

        document.save(new File(RESULT_FOLDER, "document1-with-overlay.pdf"));
    }
}

结果是

如您所见,这两个数字都来自文件1.pdf https://dl.dropboxusercontent.com/u/21842502/picas/document1.pdf以及来自的行覆盖.pdf https://dl.dropboxusercontent.com/u/21842502/picas/overlay.pdf在那儿。

Beware!此代码是概念验证,尚未准备好用于一般生产用途。它例如完全忽略Rotate页面条目...

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PDFBox 叠加失败 的相关文章

随机推荐

  • 将视图从一种布局动画化到另一种布局

    检查附图以方便解释 翻译动画可以工作 但它会在同一视图内进行动画处理 我希望视图从一种布局飞出到另一种布局 我从这里的另一个答案尝试过这个 相同布局的动画 public class Animations public Animation f
  • 无法在 PHP 中创建不区分大小写的正则表达式

    我无法在 php 中创建有效的正则表达式 我在用着i标记为正则表达式模式 但它不会对我的脚本的结果产生影响 page Test page1 test var dump preg match test i page int 0 var dum
  • 为引用的程序集引发 FileNotFoundException

    我真的很奇怪FileNotFoundException第一次尝试使用我引用的程序集中定义的类时抛出 程序集没有更改 项目文件中的位置与磁盘上的物理路径正确对应 当我将安装程序添加到 Windows 服务和安装项目时 由两个库项目 一个 Wi
  • iOS8后台获取问题

    我在 ios8 之前使用后台获取没有问题 但在 ios8 中 当我在手机上模拟后台获取时 我首先收到一条错误消息 指出我无权播放声音 因此我没有收到任何本地通知 然后打开应用程序后 应用程序崩溃 我收到这个奇怪的错误 由于未捕获的异常而终止
  • fetch.max.wait.ms 与 poll() 方法的参数

    在提出问题之前 我想指出已经有人提出了类似的问题here https stackoverflow com questions 50302119 apache kafka understanding the relationship betw
  • 是否可以在groovy函数上设置环境变量

    我知道我可以在一个阶段有一个关于詹金斯管道 声明性 的环境部分 像这样 stage Name environment NAME value steps script Do something using these env vars 我想编
  • 删除条件格式

    我正在尝试使用 C 和以下代码添加条件格式 Microsoft Office Interop Excel FormatCondition formatConditionObj null formatConditionObj Microsof
  • 检查对象是否声明为 const

    如果对象被声明为 const 我想中断编译 以下不起作用 include
  • 颤动设计曲线布局

    在颤振中 我知道我们可以画线来设计弧形布局 如下图所示 但我只是在 flutter 上学习这个功能 我无法设计它 也许在 flutter 中我们有一些实现的库或源代码 但我无法找到和设计它 请注意 屏幕右侧和曲线之间的空白可在高度和宽度上调
  • new Object{} 和 new Object(){} 有什么区别[重复]

    这个问题在这里已经有答案了 我用这种方式在 C 中定义类的对象 var something new SomeThing Property SomeProperty 这样 var something new SomeThing Propert
  • 指定的架构无效。错误:同名的多个类型

    我正在 EF 6 中工作 当我尝试运行我的项目时遇到以下问题 指定的架构无效 错误 名称为 TableName 的多种类型存在于 不同命名空间中的 EdmItemCollection 基于约定的映射 需要唯一的名称 而不考虑命名空间 Edm
  • ES6 Map:变换值

    我正在开发一个项目 经常需要转换 ES6 映射中的每个值 const positiveMap new Map hello 1 world 2 const negativeMap new Map
  • 通过blueimp jquery-fileupload异步上传多个文件

    我正在使用 jQuery 文件上传库 http github com blueimp jQuery File Upload http github com blueimp jQuery File Upload 并且我一直在思考如何使用满足以
  • 如果 0 或 "" 删除行:代码可以工作,但速度很慢

    问题 在这个论坛上的录音机和帮助下 我编写了一个代码 用于按钮 i 列有 来自第 25 行 Pcs 或一个数字 我的宏找到 Pcs 并将其更改为 然后宏删除 和 0 填充单元格的长度是可变的 所以我将 500 作为 结束 但它永远不会达到那
  • 当javaFX的控制器不足以显示内容时,它会在末尾显示“...”?

    我的问题是我可以捕获显示 的事件吗 我的意思是javaFX有API来判断内容结尾是否替换为 吗 事实上 我提出这个问题的原因是 现在我们的测试人员希望我们在一个控制器 如标签 上设置一个 TIP 如果它不足以显示 如果内容足以在控制器中显示
  • 在 C# 中产生分段错误的规范方法是什么?

    我对最短 最简洁的 C 代码感兴趣 它将可靠地产生段错误 理想情况下不会直接调用任何非托管代码 你所追求的有点不清楚 但我认为这与迄今为止的任何答案一样好 而且它是你能得到的尽可能少的 System Runtime InteropServi
  • Ionic 列表项单击在另一个 HTML 页面中显示详细信息

    我使用以下代码创建了一个项目列表
  • 使用 Node.js 从 couchdb 检索所有文档

    我正在编写一个简单的测试应用程序来试验 node js 和 couchdb 的功能 到目前为止我很喜欢它 但我遇到了障碍 我已经广泛寻找 但似乎找不到答案 我的测试服务器 一个简单的地址簿 做了两件事 如果用户去localhost 8000
  • 如何将 React 组件导出为 npm 包? Create-React-App 语法错误:意外的标记

    我创建了反应应用程序 名称为 create react app npm 在 src index js 文件中 我导出了组件以在另一个项目中使用它的 npm 包 首先 我在我的主根目录中运行了这段代码 npm run eject然后是我项目的
  • PDFBox 叠加失败

    我使用 PDFBox 1 8 8 并尝试使用以下 scala 方法将 PDDocument 与其他文档叠加 def mergeTest val home System getProperty user home val doc PDDocu