【问题标题】:Moving from PDFBox 1.x to PDFBox 2从 PDFBox 1.x 迁移到 PDFBox 2
【发布时间】:2015-11-28 01:34:34
【问题描述】:

我一直在使用 PDFBox 1.8 来处理 pdf。现在我打算迁移到 PDFBox 2.0-RC-2。我在迁移时遇到了一些问题。

使用 PDFBox 1.8,我曾经使用以下方法从 PDPage 获取令牌:

PDStream contents = page.getContents();
PDFStreamParser parser = new PDFStreamParser(contents.getStream());
parser.parse();
List<Object> tokens = parser.getTokens();

但是,page.getContents() 在 PDFBox 2 中返回一个 InputStream。如何获取 PDStream?我应该使用page.getContentStreams()(返回Iterable)并遍历它吗?此外,构造函数new PDFStreamParser(COSStream) 似乎已被弃用。

我遇到的另一个问题是图像替换。我正在使用 replaceWithStream

将一张图片替换为另一张图片
PDResources resources = page.getResources();
Iterable<COSName> xObjectNames = resources.getXObjectNames();
if (null != xObjectNames) {
    for(COSName xObjectName : xObjectNames){
        PDXObject object = resources.getXObject(xObjectName);
        if (object instanceof PDImageXObject) {
            PDImageXObject img1 = (PDImageXObject) object;
            PDImageXObject img2 = ....
            img1.getCOSStream().replaceWithStream(
                    img2.getCOSStream());
        }
    }
}

replaceWithStream 方法在 PDFBox 1.8 中已弃用,因此在 PDFBox 2.0 中已完全删除。用img2替换img1的另一种方法是什么?

【问题讨论】:

    标签: java pdfbox


    【解决方案1】:

    回答第一部分的问题:

    PDFStreamParser parser = new PDFStreamParser(page);
    parser.parse();
    List<Object> pageTokens = parser.getTokens();
    

    回答第二部分问题:

    如果两个图像具有相同的过滤器、大小等,应该是这样的:

    OutputStream os = img1.getCOSStream().createRawOutputStream();
    InputStream is = img2.getCOSStream().createRawInputStream();
    IOUtils.copy(is, os);
    is.close();
    os.close();
    

    更新: 如果它们不相同,也可以这样做:

    COSStream c1 = img1.getCOSStream();
    COSStream c2 = img2.getCOSStream();
    for (COSName name : c1.keySet())
    {
        c1.setItem(name, null);
    }
    for (COSName name : c2.keySet())
    {
        c1.setItem(name, c2.getItem(name));
    }                
    

    【讨论】:

    • @drunkenfist 对此感到抱歉。我明天会调查这个(这里是午夜)。旧图像和新图像是什么类型的图像? (jpeg、pixelmap、ccitt?)
    • 抱歉,刚才注意到 IOUtils.copy 没有按预期工作。当我尝试打开 pdf 时,我收到一条错误消息,提示图像数据不足。当我使用 replaceWithStream 时,它在 1.8 的早期版本中工作。我可以看到 InputStream 有内容。我是否需要以某种方式将 OutputStream 写回 pdf?我想不会。
    • @drunkenfist 您显然需要保存 PDF。你可能用 1.8 做的。
    • 是的,我确实保存了 pdf。图像必须具有相同的格式吗?新的肯定是 jpeg,因为我手动将其转换为 jpeg。不知道旧的是什么。如何查看图片格式?
    • 是的,正如我所说,相同的格式、相同的大小、相同的属性。使用 PDFDebugger 查看文件。
    【解决方案2】:

    第二部分的答案(本人测试):

    InputStream is = img2.getStream().getCOSObject().createRawInputStream();
    OutputStream os = img1.getStream().getCOSObject().createRawOutputStream();
    
    IOUtils.copy(is, os);
    is.close();
    os.close();
    
    img1.getStream().getCOSObject().clear();
    img1.getStream().getCOSObject().addAll(img2.getStream().getCOSObject().asUnmodifiableDictionary());
    

    【讨论】:

      猜你喜欢
      • 2019-03-15
      • 2017-03-29
      • 2018-08-10
      • 2017-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-24
      相关资源
      最近更新 更多