renderImage函数pdfbox的字体问题

问题描述 投票:0回答:1

我从PDF文档中读取页面时出现错误。此页面包含一个条形码用字体(AAAAAC + Code3de9)完成。仅当我使用renderImage函数时才会出现此错误。我使用的是pdfbox-app的2.0.17版本。

*déc. 02, 2019 9:34:13 AM org.apache.pdfbox.pdmodel.font.PDCIDFontType2 <init>
AVERTISSEMENT: Could not read embedded OTF for font AAAAAC+Code3de9
java.io.IOException: Illegal seek position: 2483278652
at org.apache.fontbox.ttf.MemoryTTFDataStream.seek(MemoryTTFDataStream.java:164)
at org.apache.fontbox.ttf.TrueTypeFont.readTable(TrueTypeFont.java:352)
at org.apache.fontbox.ttf.TTFParser.parseTables(TTFParser.java:173)
at org.apache.fontbox.ttf.TTFParser.parse(TTFParser.java:150)
at org.apache.fontbox.ttf.OTFParser.parse(OTFParser.java:79)
at org.apache.fontbox.ttf.OTFParser.parse(OTFParser.java:27)
at org.apache.fontbox.ttf.TTFParser.parse(TTFParser.java:106)
at org.apache.fontbox.ttf.OTFParser.parse(OTFParser.java:73)
at org.apache.pdfbox.pdmodel.font.PDCIDFontType2.<init>(PDCIDFontType2.java:112)
at org.apache.pdfbox.pdmodel.font.PDCIDFontType2.<init>(PDCIDFontType2.java:65)
at org.apache.pdfbox.pdmodel.font.PDFontFactory.createDescendantFont(PDFontFactory.java:139)
at org.apache.pdfbox.pdmodel.font.PDType0Font.<init>(PDType0Font.java:192)
at org.apache.pdfbox.pdmodel.font.PDFontFactory.createFont(PDFontFactory.java:97)
at org.apache.pdfbox.pdmodel.PDResources.getFont(PDResources.java:146)
at org.apache.pdfbox.contentstream.operator.text.SetFontAndSize.process(SetFontAndSize.java:61)
at org.apache.pdfbox.contentstream.PDFStreamEngine.processOperator(PDFStreamEngine.java:872)
at org.apache.pdfbox.contentstream.PDFStreamEngine.processStreamOperators(PDFStreamEngine.java:506)
at org.apache.pdfbox.contentstream.PDFStreamEngine.processStream(PDFStreamEngine.java:480)
at org.apache.pdfbox.contentstream.PDFStreamEngine.processPage(PDFStreamEngine.java:153)
at org.apache.pdfbox.rendering.PageDrawer.drawPage(PageDrawer.java:268)
at org.apache.pdfbox.rendering.PDFRenderer.renderImage(PDFRenderer.java:321)
at org.apache.pdfbox.rendering.PDFRenderer.renderImage(PDFRenderer.java:243)
at org.apache.pdfbox.rendering.PDFRenderer.renderImage(PDFRenderer.java:203)
at patrick.mart1.impose.ImposeKosmedias$1.run(ImposeKosmedias.java:370)
déc. 02, 2019 9:34:13 AM org.apache.pdfbox.pdmodel.font.PDCIDFontType2 findFontOrSubstitute
AVERTISSEMENT: Using fallback font LiberationSans for CID-keyed TrueType font AAAAAC+Code3de9*

非常感谢您的帮助

java pdfbox
1个回答
0
投票

这是基于源代码下载中的RemoveAllText.java示例。它删除了内容流中F2的选择,还删除了资源中的字体。它假定未真正使用F2,即没有与F2相关的文本。与官方示例相比,仅“ createTokensWithoutText”已更改。我保留了所有名称,即使含义有所不同,但类名称除外。

所以此代码实际上仅用于此文件或类似生成的文件。

public final class RemoveFontF2
{
    /**
     * Default constructor.
     */
    private RemoveFontF2()
    {
        // example class should not be instantiated
    }

    /**
     * This will remove all text from a PDF document.
     *
     * @param args The command line arguments.
     *
     * @throws IOException If there is an error parsing the document.
     */
    public static void main(String[] args) throws IOException
    {
        if (args.length != 2)
        {
            usage();
        }
        else
        {
            PDDocument document = PDDocument.load(new File(args[0]));
            if (document.isEncrypted())
            {
                System.err.println(
                        "Error: Encrypted documents are not supported for this example.");
                System.exit(1);
            }
            for (PDPage page : document.getPages())
            {
                List<Object> newTokens = createTokensWithoutText(page);
                PDStream newContents = new PDStream(document);
                writeTokensToStream(newContents, newTokens);
                page.setContents(newContents);
                processResources(page.getResources());
            }
            document.save(args[1]);
            document.close();
        }
    }

    private static void processResources(PDResources resources) throws IOException
    {
        for (COSName name : resources.getXObjectNames())
        {
            PDXObject xobject = resources.getXObject(name);
            if (xobject instanceof PDFormXObject)
            {
                PDFormXObject formXObject = (PDFormXObject) xobject;
                writeTokensToStream(formXObject.getContentStream(),
                        createTokensWithoutText(formXObject));
                processResources(formXObject.getResources());
            }
        }
        for (COSName name : resources.getPatternNames())
        {
            PDAbstractPattern pattern = resources.getPattern(name);
            if (pattern instanceof PDTilingPattern)
            {
                PDTilingPattern tilingPattern = (PDTilingPattern) pattern;
                writeTokensToStream(tilingPattern.getContentStream(),
                        createTokensWithoutText(tilingPattern));
                processResources(tilingPattern.getResources());
            }
        }
    }

    private static void writeTokensToStream(PDStream newContents, List<Object> newTokens) throws IOException
    {
        OutputStream out = newContents.createOutputStream(COSName.FLATE_DECODE);
        ContentStreamWriter writer = new ContentStreamWriter(out);
        writer.writeTokens(newTokens);
        out.close();
    }

    private static List<Object> createTokensWithoutText(PDContentStream contentStream) throws IOException
    {
        PDFStreamParser parser = new PDFStreamParser(contentStream);
        Object token = parser.parseNextToken();
        List<Object> newTokens = new ArrayList<Object>();
        while (token != null)
        {
            if (token instanceof Operator)
            {
                Operator op = (Operator) token;
                String opName = op.getName();
                if (OperatorName.SET_FONT_AND_SIZE.equals(opName) &&
                    newTokens.get(newTokens.size() - 2).equals(COSName.getPDFName("F2")))
                {
                    // remove the 2 arguments to this operator
                    newTokens.remove(newTokens.size() - 1);
                    newTokens.remove(newTokens.size() - 1);

                    token = parser.parseNextToken();
                    continue;
                }
            }
            newTokens.add(token);
            token = parser.parseNextToken();
        }
        // remove F2
        COSBase fontBase = contentStream.getResources().getCOSObject().getItem(COSName.FONT);
        if (fontBase instanceof COSDictionary)
        {
            ((COSDictionary) fontBase).removeItem(COSName.getPDFName("F2"));
        }
        return newTokens;
    }

    /**
     * This will print the usage for this document.
     */
    private static void usage()
    {
        System.err.println("Usage: java " + RemoveFontF2.class.getName() + " <input-pdf> <output-pdf>");
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.