0

I have looking for a solution to remove watermark from PDF generated from MS-WORD, i have used solution from following link and thats work for the files having watermark generated from Itext pdf

Community
  • 1
  • 1
saurabhiitr
  • 47
  • 1
  • 7

2 Answers2

0

Here's an Apache PDFBox solution for your file only. It is very likely that it won't work for other word files, but it is worth a try. To understand what I did, open the old and the new files with the PDFBox PDFDebugger command line application (or with itext RUPS) and look at the "Contents" entry.

The part I deleted starts with

/Artifact << /Attached [ /Top ] /Type /Pagination /Subtype /Header >> BDC

and ends with

EMC

However that one also contained color and font settings so I kept these. It is possible that in a real file, this segment will contain more useful data (after all, it is named "Header") and different types of color settings, so more logic will be needed.

PDDocument document = PDDocument.load(new File("Saura.pdf"));
if (document.isEncrypted())
{
    System.err.println("Error: Encrypted documents are not supported for this example.");
    System.exit(1);
}
for (PDPage page : document.getPages())
{
    PDFStreamParser parser = new PDFStreamParser(page);
    parser.parse();
    List<Object> tokens = parser.getTokens();
    List<Object> newTokens = new ArrayList<Object>();
    List<Object> parameters = new ArrayList<Object>();
    boolean skip = false;
    // PDF content stream tokens have the forn
    // paramater1...parameterN operator
    for (Object token : tokens)
    {
        if (token instanceof Operator)
        {
            Operator op = (Operator) token;
            if ("BDC".equals(op.getName()))
            {
                // "Watermark" starts with
                // /Artifact << /Attached [ /Top ] /Type /Pagination /Subtype /Header >> BDC
                if (parameters.size() == 2 && COSName.ARTIFACT.equals(parameters.get(0)) && parameters.get(1) instanceof COSDictionary)
                {
                    COSDictionary dict = (COSDictionary) parameters.get(1);
                    if (COSName.getPDFName("Header").equals(dict.getItem(COSName.SUBTYPE)))
                    {
                        skip = true;
                    }
                }
            }
            if (!skip || "g".equals(op.getName()) || "G".equals(op.getName()) || "Tf".equals(op.getName()))
            {
                // even when skipping, don't remove color and font settings
                newTokens.addAll(parameters);
                newTokens.add(op);
            }
            if ("EMC".equals(op.getName()))
            {
                // "Watermark" ends with EMC
                skip = false;                            
            }
            parameters = new ArrayList<Object>();
        }
        else
        {
            parameters.add(token);
        }
    }
    PDStream newContents = new PDStream(document);
    OutputStream out = newContents.createOutputStream(COSName.FLATE_DECODE);
    ContentStreamWriter writer = new ContentStreamWriter(out);
    writer.writeTokens(newTokens);
    out.close();
    page.setContents(newContents);
}
document.save(new File("Saura2.pdf"));
Tilman Hausherr
  • 17,731
  • 7
  • 58
  • 97
0

I just wrote a piece of code in Kotlin to remove watermark. I know nothing about PDF, but hope it helps.

    @Test
    fun test() {
        val pdf = PDDocument.load(File("/tmp/original.pdf"))

        pdf.pages.forEachIndexed { index, p ->
            val tokens = ArrayList(PDFStreamParser(p).apply { parse() }.tokens)
            val found = tokens.indexOfLast {
                it is COSDictionary && it.toString().contains("Watermark")
            }
            if (found >= 0) {
                runCatching {
                    val start = (found downTo 0).first { i ->
                        tokens[i].let { it is Operator && it.name == "Q" }
                    }
                    val end = (found until tokens.size).first { i ->
                        tokens[i].let { it is Operator && it.name == "Q" }
                    }
                    //remove unwanted
                    tokens.subList(start, end).clear()

                    p.setContents(PDStream(pdf).apply {
                        createOutputStream(COSName.FLATE_DECODE).use {
                            ContentStreamWriter(it).writeTokens(tokens)
                        }
                    })
                }.onFailure {
                    //debug something.
                    println("err: $p, $index")
                    throw it
                }
            }
        }

        pdf.save(File("/tmp/output.pdf"))
    }