我一直在寻找从 MS-WORD 生成的 PDF 中删除水印的解决方案, 我使用了以下link的解决方案,这适用于从Itext生成水印的文件pdf
答案 0 :(得分:0)
这是适用于您的文件的Apache PDFBox解决方案。它很可能不适用于其他word文件,但值得一试。要了解我的操作,请使用PDFBox PDFDebugger命令行应用程序(或使用itext RUPS)打开旧文件和新文件,然后查看“内容”条目。
我删除的部分以
开头/Artifact << /Attached [ /Top ] /Type /Pagination /Subtype /Header >> BDC
以
结束EMC
然而,那个还包含颜色和字体设置,所以我保留了这些。在真实文件中,该段可能包含更多有用的数据(毕竟,它被命名为“Header”)和不同类型的颜色设置,因此需要更多的逻辑。
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"));
答案 1 :(得分:0)
我刚刚在Kotlin中编写了一段代码来删除水印。 我对PDF一无所知,但希望对您有所帮助。
@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"))
}