Java Code Examples for org.apache.pdfbox.cos.COSDictionary#keySet()

The following examples show how to use org.apache.pdfbox.cos.COSDictionary#keySet() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: PDAppearanceEntry.java    From gcs with Mozilla Public License 2.0 6 votes vote down vote up
/**
 * Returns the entry as an appearance subdictionary.
 *
 * @throws IllegalStateException if this entry is not an appearance subdictionary
 */
public Map<COSName, PDAppearanceStream> getSubDictionary()
{
    if (!isSubDictionary())
    {
        throw new IllegalStateException("This entry is not an appearance subdictionary");
    }

    COSDictionary dict = (COSDictionary) entry;
    Map<COSName, PDAppearanceStream> map = new HashMap<COSName, PDAppearanceStream>();

    for (COSName name : dict.keySet())
    {
        COSBase value = dict.getDictionaryObject(name);

        // the file from PDFBOX-1599 contains /null as its entry, so we skip non-stream entries
        if (value instanceof COSStream)
        {
            map.put(name, new PDAppearanceStream((COSStream) value));
        }
    }

    return new COSDictionaryMap<COSName, PDAppearanceStream>(map, dict);
}
 
Example 2
Source File: PDSeedValueCertificate.java    From gcs with Mozilla Public License 2.0 6 votes vote down vote up
/**
 * Returns list of maps that contains subject distinguished names like [(cn: John Doe, o: Doe), (cn: John Smith)]
 * both keys are typically of the form 'cn', 'o', 'email', '2.5.4.43'; and values are text strings.
 * 
 * @return a list of maps containing the subject distinguished names
 */
public List<Map<String, String>> getSubjectDN()
{
    COSBase base = this.dictionary.getDictionaryObject(COSName.SUBJECT_DN);
    if (base instanceof COSArray)
    {
        COSArray cosArray = (COSArray) base;
        List subjectDNList = cosArray.toList();
        List<Map<String, String>> result = new LinkedList<Map<String, String>>();
        for (Object subjectDNItem : subjectDNList)
        {
            if (subjectDNItem instanceof COSDictionary)
            {
                COSDictionary subjectDNItemDict = (COSDictionary) subjectDNItem;
                Map<String, String> subjectDNMap = new HashMap<String, String>();
                for (COSName key : subjectDNItemDict.keySet())
                {
                    subjectDNMap.put(key.getName(), subjectDNItemDict.getString(key));
                }
                result.add(subjectDNMap);
            }
        }
        return result;
    }
    return null;
}
 
Example 3
Source File: PDResources.java    From gcs with Mozilla Public License 2.0 5 votes vote down vote up
/**
 * Returns the resource names of the given kind.
 * 
 * @return the names of all resources of the given kind.
 */
private Iterable<COSName> getNames(COSName kind)
{
    COSDictionary dict = (COSDictionary)resources.getDictionaryObject(kind);
    if (dict == null)
    {
        return Collections.emptySet();
    }
    return dict.keySet();
}
 
Example 4
Source File: PDType3Font.java    From gcs with Mozilla Public License 2.0 5 votes vote down vote up
private BoundingBox generateBoundingBox()
{
    PDRectangle rect = getFontBBox();
    if (rect.getLowerLeftX() == 0 && rect.getLowerLeftY() == 0
            && rect.getUpperRightX() == 0 && rect.getUpperRightY() == 0)
    {
        // Plan B: get the max bounding box of the glyphs
        COSDictionary cp = getCharProcs();
        for (COSName name : cp.keySet())
        {
            COSBase base = cp.getDictionaryObject(name);
            if (base instanceof COSStream)
            {
                PDType3CharProc charProc = new PDType3CharProc(this, (COSStream) base);
                try
                {
                    PDRectangle glyphBBox = charProc.getGlyphBBox();
                    if (glyphBBox == null)
                    {
                        continue;
                    }
                    rect.setLowerLeftX(Math.min(rect.getLowerLeftX(), glyphBBox.getLowerLeftX()));
                    rect.setLowerLeftY(Math.min(rect.getLowerLeftY(), glyphBBox.getLowerLeftY()));
                    rect.setUpperRightX(Math.max(rect.getUpperRightX(), glyphBBox.getUpperRightX()));
                    rect.setUpperRightY(Math.max(rect.getUpperRightY(), glyphBBox.getUpperRightY()));
                }
                catch (IOException ex)
                {
                    // ignore
                }
            }
        }
    }
    return new BoundingBox(rect.getLowerLeftX(), rect.getLowerLeftY(),
            rect.getUpperRightX(), rect.getUpperRightY());
}
 
Example 5
Source File: OptimizeAfterMerge.java    From testarea-pdfbox2 with Apache License 2.0 5 votes vote down vote up
/**
 * Helper method for {@link #optimize(PDDocument)} - the method
 * collects complex objects (arrays, dictionaries, streams) in
 * a document and the references to it.
 * 
 * @see #testOptimizeDummy()
 */
Map<COSBase, Collection<Reference>> findComplexObjects(PDDocument pdDocument) {
    COSDictionary catalogDictionary = pdDocument.getDocumentCatalog().getCOSObject();
    Map<COSBase, Collection<Reference>> incomingReferences = new HashMap<>();
    incomingReferences.put(catalogDictionary, new ArrayList<>());

    Set<COSBase> lastPass = Collections.<COSBase>singleton(catalogDictionary);
    Set<COSBase> thisPass = new HashSet<>();
    while(!lastPass.isEmpty()) {
        for (COSBase object : lastPass) {
            if (object instanceof COSArray) {
                COSArray array = (COSArray) object;
                for (int i = 0; i < array.size(); i++) {
                    addTarget(new ArrayReference(array, i), incomingReferences, thisPass);
                }
            } else if (object instanceof COSDictionary) {
                COSDictionary dictionary = (COSDictionary) object;
                for (COSName key : dictionary.keySet()) {
                    addTarget(new DictionaryReference(dictionary, key), incomingReferences, thisPass);
                }
            }
        }
        lastPass = thisPass;
        thisPass = new HashSet<>();
    }
    return incomingReferences;
}
 
Example 6
Source File: OptimizeAfterMerge.java    From testarea-pdfbox2 with Apache License 2.0 5 votes vote down vote up
/**
 * Helper method for {@link #mergeRun(Map, List)} - this method
 * checks whether two PDF objects actually are equal.
 * 
 * @see #testOptimizeDummy()
 */
boolean equals(COSBase a, COSBase b) {
    if (a instanceof COSArray) {
        if (b instanceof COSArray) {
            COSArray aArray = (COSArray) a;
            COSArray bArray = (COSArray) b;
            if (aArray.size() == bArray.size()) {
                for (int i=0; i < aArray.size(); i++) {
                    if (!resolve(aArray.get(i)).equals(resolve(bArray.get(i))))
                        return false;
                }
                return true;
            }
        }
    } else if (a instanceof COSDictionary) {
        if (b instanceof COSDictionary) {
            COSDictionary aDict = (COSDictionary) a;
            COSDictionary bDict = (COSDictionary) b;
            Set<COSName> keys = aDict.keySet();
            // As proposed by jchobantonov on github, we can compare dictionary sizes
            // here instead of the dictionaries themselves as we compare the values
            // key by key in the body of the if.
            if (keys.size() == bDict.keySet().size()) {
                for (COSName key : keys) {
                    if (!resolve(aDict.getItem(key)).equals(bDict.getItem(key)))
                        return false;
                }
                // In case of COSStreams we strictly speaking should
                // also compare the stream contents here. But apparently
                // their hashes coincide well enough for the original
                // hashing equality, so let's just assume...
                return true;
            }
        }
    }
    return false;
}
 
Example 7
Source File: OptimizeAfterMerge.java    From testarea-pdfbox2 with Apache License 2.0 5 votes vote down vote up
/**
 * <a href="https://stackoverflow.com/questions/53420344/ho-to-reduce-the-size-of-merged-pdf-a1-b-files-with-pdfbox-or-other-java-library">
 * Ho to reduce the size of merged PDF A1/b Files with pdfbox or other java library
 * </a>
 * <br/>
 * <a href="https://datentransfer.sparkassenverlag.de/my/transfers/5q8eskgne52npemx8kid7728zk1hq3f993dfat8his">
 * dummy.pdf
 * </a>
 * <p>
 * This is the code the OP himself posted as his solution. This only works if
 * (a) all font programs embedded for the same name indeed are identical, and
 * if (b) all fonts to consider are in the immediate page resources, not the
 * resources of some referred to xobject or pattern. If those conditions are
 * fulfilled, though, it very likely is much faster than the approach in
 * {@link #optimize(PDDocument)}. For the example file provided by the OP,
 * its result is nearly as small.
 * </p>
 */
@Test
public void testOptimizeLikeSchowaveDummy() throws IOException {
    try (   InputStream resource = getClass().getResourceAsStream("dummy.pdf")  ) {
        PDDocument doc = Loader.loadPDF(resource);

        Map<String, COSBase> fontFileCache = new HashMap<>();
        for (int pageNumber = 0; pageNumber < doc.getNumberOfPages(); pageNumber++) {
            final PDPage page = doc.getPage(pageNumber);
            COSDictionary pageDictionary = (COSDictionary) page.getResources().getCOSObject().getDictionaryObject(COSName.FONT);
            for (COSName currentFont : pageDictionary.keySet()) {
                COSDictionary fontDictionary = (COSDictionary) pageDictionary.getDictionaryObject(currentFont);
                for (COSName actualFont : fontDictionary.keySet()) {
                    COSBase actualFontDictionaryObject = fontDictionary.getDictionaryObject(actualFont);
                    if (actualFontDictionaryObject instanceof COSDictionary) {
                        COSDictionary fontFile = (COSDictionary) actualFontDictionaryObject;
                        if (fontFile.getItem(COSName.FONT_NAME) instanceof COSName) {
                            COSName fontName = (COSName) fontFile.getItem(COSName.FONT_NAME);
                            fontFileCache.computeIfAbsent(fontName.getName(), key -> fontFile.getItem(COSName.FONT_FILE2));
                            fontFile.setItem(COSName.FONT_FILE2, fontFileCache.get(fontName.getName()));
                        }
                    }
                }
            }
        }

        doc.save(new File(RESULT_FOLDER, "dummy-optimized-like-schowave.pdf"));
    }
}
 
Example 8
Source File: COSDictionaryMap.java    From gcs with Mozilla Public License 2.0 4 votes vote down vote up
/**
 * This will take a COS dictionary and convert it into COSDictionaryMap.  All cos
 * objects will be converted to their primitive form.
 *
 * @param map The COS mappings.
 * @return A standard java map.
 * @throws IOException If there is an error during the conversion.
 */
public static COSDictionaryMap<String, Object> convertBasicTypesToMap( COSDictionary map ) throws IOException
{
    COSDictionaryMap<String, Object> retval = null;
    if( map != null )
    {
        Map<String, Object> actualMap = new HashMap<String, Object>();
        for( COSName key : map.keySet() )
        {
            COSBase cosObj = map.getDictionaryObject( key );
            Object actualObject = null;
            if( cosObj instanceof COSString )
            {
                actualObject = ((COSString)cosObj).getString();
            }
            else if( cosObj instanceof COSInteger )
            {
                actualObject = ((COSInteger)cosObj).intValue();
            }
            else if( cosObj instanceof COSName )
            {
                actualObject = ((COSName)cosObj).getName();
            }
            else if( cosObj instanceof COSFloat )
            {
                actualObject = ((COSFloat)cosObj).floatValue();
            }
            else if( cosObj instanceof COSBoolean )
            {
                actualObject = ((COSBoolean)cosObj).getValue() ? Boolean.TRUE : Boolean.FALSE;
            }
            else
            {
                throw new IOException( "Error:unknown type of object to convert:" + cosObj );
            }
            actualMap.put( key.getName(), actualObject );
        }
        retval = new COSDictionaryMap<String, Object>( actualMap, map );
    }

    return retval;
}
 
Example 9
Source File: ContentStreamWriter.java    From gcs with Mozilla Public License 2.0 4 votes vote down vote up
private void writeObject( Object o ) throws IOException
{
    if( o instanceof COSString )
    {
        COSWriter.writeString((COSString)o, output);
        output.write( SPACE );
    }
    else if( o instanceof COSFloat )
    {
        ((COSFloat)o).writePDF( output );
        output.write( SPACE );
    }
    else if( o instanceof COSInteger )
    {
        ((COSInteger)o).writePDF( output );
        output.write( SPACE );
    }
    else if( o instanceof COSBoolean )
    {
        ((COSBoolean)o).writePDF( output );
        output.write( SPACE );
    }
    else if( o instanceof COSName )
    {
        ((COSName)o).writePDF( output );
        output.write( SPACE );
    }
    else if( o instanceof COSArray )
    {
        COSArray array = (COSArray)o;
        output.write(COSWriter.ARRAY_OPEN);
        for( int i=0; i<array.size(); i++ )
        {
            writeObject( array.get( i ) );
            output.write( SPACE );
        }

        output.write( COSWriter.ARRAY_CLOSE );
    }
    else if( o instanceof COSDictionary )
    {
        COSDictionary obj = (COSDictionary)o;
        output.write( COSWriter.DICT_OPEN );
        for (Map.Entry<COSName, COSBase> entry : obj.entrySet())
        {
            if (entry.getValue() != null)
            {
                writeObject( entry.getKey() );
                output.write( SPACE );
                writeObject( entry.getValue() );
                output.write( SPACE );
            }
        }
        output.write( COSWriter.DICT_CLOSE );
        output.write( SPACE );
    }
    else if( o instanceof Operator)
    {
        Operator op = (Operator)o;
        if (op.getName().equals(OperatorName.BEGIN_INLINE_IMAGE))
        {
            output.write(OperatorName.BEGIN_INLINE_IMAGE.getBytes(Charsets.ISO_8859_1));
            COSDictionary dic = op.getImageParameters();
            for( COSName key : dic.keySet() )
            {
                Object value = dic.getDictionaryObject( key );
                key.writePDF( output );
                output.write( SPACE );
                writeObject( value );
                output.write( EOL );
            }
            output.write(OperatorName.BEGIN_INLINE_IMAGE_DATA.getBytes(Charsets.ISO_8859_1));
            output.write( EOL );
            output.write( op.getImageData() );
            output.write( EOL );
            output.write(OperatorName.END_INLINE_IMAGE.getBytes(Charsets.ISO_8859_1));
            output.write( EOL );
        }
        else
        {
            output.write( op.getName().getBytes(Charsets.ISO_8859_1) );
            output.write( EOL );
        }
    }
    else
    {
        throw new IOException( "Error:Unknown type in content stream:" + o );
    }
}
 
Example 10
Source File: RenderType3Character.java    From testarea-pdfbox2 with Apache License 2.0 4 votes vote down vote up
/**
     * <a href="http://stackoverflow.com/questions/42032729/render-type3-font-character-as-image-using-pdfbox">
     * Render Type3 font character as image using PDFBox
     * </a>
     * <br/>
     * <a href="https://drive.google.com/file/d/0B0f6X4SAMh2KRDJTbm4tb3E1a1U/view">
     * 4700198773.pdf
     * </a>
     * from
     * <a href="http://stackoverflow.com/questions/37754112/extract-text-with-custom-font-result-non-readble">
     * extract text with custom font result non readble
     * </a>
     * <p>
     * This test shows how one can render individual Type 3 font glyphs as bitmaps.
     * Unfortunately PDFBox out-of-the-box does not provide a class to render contents
     * of arbitrary XObjects, merely for rendering pages; thus, we simply create a page
     * with the glyph in question and render that page.   
     * </p>
     * <p>
     * As the OP did not provide a sample PDF, we simply use one from another
     * stackoverflow question. There obviously might remain issues with the
     * OP's files.
     * </p>
     */
    @Test
    public void testRender4700198773() throws IOException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
    {
        Method PDPageContentStreamWrite = PDPageContentStream.class.getSuperclass().getDeclaredMethod("write", String.class);
        PDPageContentStreamWrite.setAccessible(true);

        try (   InputStream resource = getClass().getResourceAsStream("4700198773.pdf"))
        {
            PDDocument document = Loader.loadPDF(resource);

            PDPage page = document.getPage(0);
            PDResources pageResources = page.getResources();
            COSName f1Name = COSName.getPDFName("F1");
            PDType3Font fontF1 = (PDType3Font) pageResources.getFont(f1Name);
            Map<String, Integer> f1NameToCode = fontF1.getEncoding().getNameToCodeMap();

            COSDictionary charProcsDictionary = fontF1.getCharProcs();
            for (COSName key : charProcsDictionary.keySet())
            {
                COSStream stream = (COSStream) charProcsDictionary.getDictionaryObject(key);
                PDType3CharProc charProc = new PDType3CharProc(fontF1, stream);
                PDRectangle bbox = charProc.getGlyphBBox();
                if (bbox == null)
                    bbox = charProc.getBBox();
                Integer code = f1NameToCode.get(key.getName());

                if (code != null)
                {
                    PDDocument charDocument = new PDDocument();
                    PDPage charPage = new PDPage(bbox);
                    charDocument.addPage(charPage);
                    charPage.setResources(pageResources);
                    PDPageContentStream charContentStream = new PDPageContentStream(charDocument, charPage);
                    charContentStream.beginText();
                    charContentStream.setFont(fontF1, bbox.getHeight());
//                    charContentStream.write(String.format("<%2X> Tj\n", code).getBytes());
                    PDPageContentStreamWrite.invoke(charContentStream, String.format("<%2X> Tj\n", code));
                    charContentStream.endText();
                    charContentStream.close();

                    File result = new File(RESULT_FOLDER, String.format("4700198773-%s-%s.png", key.getName(), code));
                    PDFRenderer renderer = new PDFRenderer(charDocument);
                    BufferedImage image = renderer.renderImageWithDPI(0, 96);
                    ImageIO.write(image, "PNG", result);
                    charDocument.save(new File(RESULT_FOLDER, String.format("4700198773-%s-%s.pdf", key.getName(), code)));
                    charDocument.close();
                }
            }
        }
    }
 
Example 11
Source File: RenderType3Character.java    From testarea-pdfbox2 with Apache License 2.0 4 votes vote down vote up
/**
 * <a href="http://stackoverflow.com/questions/42032729/render-type3-font-character-as-image-using-pdfbox">
 * Render Type3 font character as image using PDFBox
 * </a>
 * <br/>
 * <a href="https://drive.google.com/file/d/0B0f6X4SAMh2KRDJTbm4tb3E1a1U/view">
 * 4700198773.pdf
 * </a>
 * from
 * <a href="http://stackoverflow.com/questions/37754112/extract-text-with-custom-font-result-non-readble">
 * extract text with custom font result non readble
 * </a>
 * <p>
 * This test shows how one can render individual Type 3 font glyphs as bitmaps.
 * Unfortunately PDFBox out-of-the-box does not provide a class to render contents
 * of arbitrary XObjects, merely for rendering pages; thus, we simply create a page
 * with the glyph in question and render that page.   
 * </p>
 * <p>
 * As the OP did not provide a sample PDF, we simply use one from another
 * stackoverflow question. There obviously might remain issues with the
 * OP's files.
 * </p>
 */
@Test
public void testRenderSdnList() throws IOException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException
{
    Method PDPageContentStreamWrite = PDPageContentStream.class.getSuperclass().getDeclaredMethod("write", String.class);
    PDPageContentStreamWrite.setAccessible(true);

    try (   InputStream resource = getClass().getResourceAsStream("sdnlist.pdf"))
    {
        PDDocument document = Loader.loadPDF(resource);

        PDPage page = document.getPage(1);
        PDResources pageResources = page.getResources();
        COSName f1Name = COSName.getPDFName("R144");
        PDType3Font fontF1 = (PDType3Font) pageResources.getFont(f1Name);
        Map<String, Integer> f1NameToCode = fontF1.getEncoding().getNameToCodeMap();

        COSDictionary charProcsDictionary = fontF1.getCharProcs();
        for (COSName key : charProcsDictionary.keySet())
        {
            COSStream stream = (COSStream) charProcsDictionary.getDictionaryObject(key);
            PDType3CharProc charProc = new PDType3CharProc(fontF1, stream);
            PDRectangle bbox = charProc.getGlyphBBox();
            if (bbox == null)
                bbox = charProc.getBBox();
            Integer code = f1NameToCode.get(key.getName());

            if (code != null)
            {
                PDDocument charDocument = new PDDocument();
                PDPage charPage = new PDPage(bbox);
                charDocument.addPage(charPage);
                charPage.setResources(pageResources);
                PDPageContentStream charContentStream = new PDPageContentStream(charDocument, charPage);
                charContentStream.beginText();
                charContentStream.setFont(fontF1, bbox.getHeight());
                //charContentStream.getOutputStream().write(String.format("<%2X> Tj\n", code).getBytes());
                PDPageContentStreamWrite.invoke(charContentStream, String.format("<%2X> Tj\n", code));
                charContentStream.endText();
                charContentStream.close();

                File result = new File(RESULT_FOLDER, String.format("sdnlist-%s-%s.png", key.getName(), code));
                PDFRenderer renderer = new PDFRenderer(charDocument);
                BufferedImage image = renderer.renderImageWithDPI(0, 96);
                ImageIO.write(image, "PNG", result);
                charDocument.save(new File(RESULT_FOLDER, String.format("sdnlist-%s-%s.pdf", key.getName(), code)));
                charDocument.close();
            }
        }
    }
}