[英]How do I remove watermark Xobject from pdf?
我想從 pdf 文件中刪除水印。 它可能是由 Acrobat 開發的軟件創建的。
書是我的。 任何有權訪問稱為 EBSCO 的學術服務的人都可以使用它。 許多學術圖書館都有它; 所以我的圖書館。 我下載了這本書,我想打印其中的某些部分而沒有煩人的水印。
"ADBE_CompoundType" Editable watermarks (headers, footers, stamps) created by Acrobat
信息取自此處。
我將PdfContentStreamEditor
class 用於由mkl創建並在 SO 上發布的pdfbox
作為問題的答案。 我重寫了一種方法。 這里是:
@Override
protected void write(final ContentStreamWriter contentStreamWriter,
final Operator operator,
final List < COSBase > operands) throws IOException {
if (isWatermark(operator, operands)) {
final COSName xObjectName = COSName.getPDFName("Fm0");
final PDXObject fm0 = page.getResources().getXObject(xObjectName);
if (fm0 != null) {
final COSObject pieceInfo = fm0.getCOSObject()
.getCOSObject(COSName.getPDFName("PieceInfo"));
if (pieceInfo != null) {
final COSBase adbeCompoundType = pieceInfo.getDictionaryObject(
COSName.getPDFName("ADBE_CompoundType"));
if (adbeCompoundType != null) {
final COSBase privateKey = ((COSDictionary) adbeCompoundType)
.getDictionaryObject("Private");
if ("Watermark".equals(((COSName) privateKey).getName())) {
final PDResources resources = page.getResources();
resources.getCOSObject().removeItem(xObjectName);
page.getResources().getCOSObject().setNeedToBeUpdated(true);
return;
}
}
}
}
}
super.write(contentStreamWriter, operator, operands);
}
和輔助方法:
private boolean isWatermark(final Operator operator,
final List < COSBase > operands) {
final String operatorString = operator.getName();
return operatorString.equals("Do") &&
operands.size() == 1 && ((COSName) operands.get(0)).getName().equals("Fm0");
}
該代碼似乎工作正常 - 任何頁面上都沒有顯示水印。 但是,我無法擺脫帶有水印的 object。 我試圖用下面的代碼行刪除它,不幸的是 object 沒有被刪除。
final PDResources resources = page.getResources(); resources.getCOSObject().removeItem(xObjectName); page.getResources().getCOSObject().setNeedToBeUpdated(true);
這是來自 pdfdebugger 的屏幕截圖,帶有水印 object:
這是水印文本。 我找不到如何檢查水印 object 是否包含此文本,我想知道如何執行此操作。
您嘗試從這樣的資源中刪除 XObject Fm0 :
final PDResources resources = page.getResources();
resources.getCOSObject().removeItem(xObjectName);
也就是說,您獲取資源的 COS(字典)object 並嘗試刪除Fm0 (在xObjectName
中)條目。
但是,如果您仔細查看屏幕截圖,您會發現Fm0條目不直接位於Resources字典中。 相反,有一個嵌套的XObject字典條目,其中又是Fm0條目。
因此,以下應該起作用:
final PDResources resources = page.getResources();
COSDictionary dict = (COSDictionary) (resources.getCOSObject().getDictionaryObject(COSName.XOBJECT));
dict.removeItem(xObjectName);
PDResources
有一些輔助方法,所以下面的方法也應該有效:
page.getResources().put(xObjectName, (PDXObject)null);
您提到這本書屬於您,因此您有權刪除水印。 情況並非自動如此。 根據法律(全球和當地)和適用的合同,您可能僅獲得以當前形式(包括水印)使用該圖書的權利。 請確保您了解使用本書的限制條件。
另外我想知道如果水印不再顯示而你只是想更改文件以在沒有水印的情況下打印,你為什么要擺脫那個 XObject ...
雖然mkl已經回答了這個問題,但我還是想分享一個使用iText
庫的解決方案,盡管我更喜歡pdfbox
而不是iText
,因為前者是免費提供的。 iText
代碼比pdfbox
的代碼更簡潔。 這是因為當水印 object 被刪除后,它會自動不顯示在任何頁面上。
for (int i = 1; i <= document.getNumberOfPages(); i++) {
final PdfPage page = document.getPage(i);
final PdfDictionary xObject = page.getResources().getResource(PdfName.XObject);
if (xObject != null) {
final PdfStream fm0 = xObject.getAsStream(new PdfName("Fm0"));
if (fm0 != null) {
final PdfDictionary pieceInfo = fm0.getAsDictionary(new PdfName("PieceInfo"));
if (pieceInfo != null) {
final PdfDictionary adbeCompoundType = pieceInfo.getAsDictionary(
new PdfName("ADBE_CompoundType"));
if (adbeCompoundType != null) {
final PdfName privateKey = adbeCompoundType.getAsName(PdfName.Private);
if (privateKey != null) {
if ("Watermark".equals(privateKey.getValue())) {
xObject.remove(new PdfName("Fm0"));
}
}
}
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.