PDFBox删除图像后出现错误 – 此页面存在错误。Acrobat可能无法正确显示页面。

huangapple go评论109阅读模式
英文:

PDFBox Error After Deleting Image - An error exists on this page. Acrobat may not display the page correctly

问题

  1. 我正在使用pdfbox库的2.0版本我必须从页面中删除所选图像并添加另一个图像它可以正常运行但是当我打开该文件时会显示一个警告消息***此页面存在错误Acrobat可能无法正确显示页面***如下是屏幕截图
  2. ![错误图片][1]
  3. 下面是删除图像并添加其他图像的代码示例:(已编辑并修复
  4. ```java
  5. public static void removeImages(String pdfFile) throws Exception {
  6. PDDocument document = PDDocument.load(new File(pdfFile));
  7. for (PDPage page : document.getPages()) {
  8. PDResources pdResources = page.getResources();
  9. String[] qrCodeCosName = new String[1];
  10. pdResources.getXObjectNames().forEach(propertyName -> {
  11. if (!pdResources.isImageXObject(propertyName)) {
  12. return;
  13. }
  14. PDXObject o;
  15. try {
  16. o = pdResources.getXObject(propertyName);
  17. if (o instanceof PDImageXObject) {
  18. PDImageXObject pdImageXObject = (PDImageXObject) o;
  19. if (pdImageXObject.getMetadata() != null) {
  20. // 从资源中移除
  21. ((COSDictionary) pdResources.getCOSObject().getDictionaryObject(COSName.XOBJECT))
  22. .removeItem(propertyName);
  23. qrCodeCosName[0] = propertyName.getName();
  24. }
  25. }
  26. } catch (IOException e) {
  27. e.printStackTrace();
  28. }
  29. });
  30. PDFStreamParser parser = new PDFStreamParser(page);
  31. parser.parse();
  32. List<Object> tokens = parser.getTokens();
  33. System.out.println("原始 tokens 大小:" + tokens.size());
  34. List<Object> newTokens = new ArrayList<Object>();
  35. for (int j = 0; j < tokens.size(); j++) {
  36. Object token = tokens.get(j);
  37. if (token instanceof Operator) {
  38. Operator op = (Operator) token;
  39. // 找到图像 - 删除它
  40. if (op.getName().equals("Do")) {
  41. COSName cosName = (COSName) tokens.get(j - 1);
  42. if (cosName.getName().equals(qrCodeCosName[0])) {
  43. newTokens.remove(newTokens.size() - 1);
  44. continue;
  45. }
  46. }
  47. newTokens.add(token);
  48. }
  49. System.out.println("tokens 大小:" + newTokens.size());
  50. PDStream newContents = new PDStream(document);
  51. OutputStream out = newContents.createOutputStream();
  52. ContentStreamWriter writer = new ContentStreamWriter(out);
  53. writer.writeTokens(newTokens);
  54. out.close();
  55. page.setContents(newContents);
  56. // 添加其他图像
  57. PDImageXObject pdImage = PDImageXObject.createFromFile("D:\\copy\\ind.png", document);
  58. PDPageContentStream contents = new PDPageContentStream(document, page,
  59. PDPageContentStream.AppendMode.PREPEND, true, true);
  60. contents.saveGraphicsState();
  61. // 在PDF文档中绘制图像
  62. contents.drawImage(pdImage, 0, 0, 50, 30);
  63. contents.restoreGraphicsState();
  64. System.out.println("成功插入图像。");
  65. // 关闭 PDPageContentStream 对象
  66. contents.close();
  67. }
  68. document.save("RemoveImage.pdf");
  69. document.close();
  70. }
  71. }

请帮忙解决这个问题。
同时,期待关于其他代码审查意见,以使此操作正常运行。 PDFBox删除图像后出现错误 – 此页面存在错误。Acrobat可能无法正确显示页面。

  1. [1]: https://i.stack.imgur.com/VJaec.png
  2. <details>
  3. <summary>英文:</summary>
  4. I am using the pdfbox library 2.0 version. I have to remove the selected image from the page and add another image. It works properly. But when I open that file it shows a warning message: ***An error exists on this page. Acrobat may not display the page correctly***. and the screenshot is as below:
  5. ![Error Image][1]
  6. Herewith sharing the code to delete an image and add other image:**(EDITTED with Fix)**
  7. public static void removeImages(String pdfFile) throws Exception {
  8. PDDocument document = PDDocument.load(new File(pdfFile));
  9. for (PDPage page : document.getPages()) {
  10. PDResources pdResources = page.getResources();
  11. String[] qrCodeCosName = new String[1];
  12. pdResources.getXObjectNames().forEach(propertyName -&gt; {
  13. if (!pdResources.isImageXObject(propertyName)) {
  14. return;
  15. }
  16. PDXObject o;
  17. try {
  18. o = pdResources.getXObject(propertyName);
  19. if (o instanceof PDImageXObject) {
  20. PDImageXObject pdImageXObject = (PDImageXObject) o;
  21. if (pdImageXObject.getMetadata() != null) {
  22. // TO REMOVE FROM RESOURCE
  23. ((COSDictionary) pdResources.getCOSObject().getDictionaryObject(COSName.XOBJECT))
  24. .removeItem(propertyName);
  25. qrCodeCosName[0] = propertyName.getName();
  26. }
  27. }
  28. } catch (IOException e) {
  29. e.printStackTrace();
  30. }
  31. });
  32. PDFStreamParser parser = new PDFStreamParser(page);
  33. parser.parse();
  34. List&lt;Object&gt; tokens = parser.getTokens();
  35. System.out.println(&quot;Original tokens size&quot; + tokens.size());
  36. List&lt;Object&gt; newTokens = new ArrayList&lt;Object&gt;();
  37. for (int j = 0; j &lt; tokens.size(); j++) {
  38. Object token = tokens.get(j);
  39. if (token instanceof Operator) {
  40. Operator op = (Operator) token;
  41. // find image - remove it
  42. if (op.getName().equals(&quot;Do&quot;)) {
  43. COSName cosName = (COSName) tokens.get(j - 1);
  44. if (cosName.getName().equals(qrCodeCosName[0])) {
  45. newTokens.remove(newTokens.size() - 1);
  46. continue;
  47. }
  48. }
  49. newTokens.add(token);
  50. }
  51. System.out.println(&quot;tokens size&quot; + newTokens.size());
  52. PDStream newContents = new PDStream(document);
  53. OutputStream out = newContents.createOutputStream();
  54. ContentStreamWriter writer = new ContentStreamWriter(out);
  55. writer.writeTokens(newTokens);
  56. out.close();
  57. page.setContents(newContents);
  58. // ADD OTHER IMAGE
  59. PDImageXObject pdImage = PDImageXObject.createFromFile(&quot;D:\\copy\\ind.png&quot;, document);
  60. PDPageContentStream contents = new PDPageContentStream(document, page,
  61. PDPageContentStream.AppendMode.PREPEND, true, true);
  62. contents.saveGraphicsState();
  63. // Drawing the image in the PDF document
  64. contents.drawImage(pdImage, 0, 0, 50, 30);
  65. contents.restoreGraphicsState();
  66. System.out.println(&quot;Image inserted Successfully.&quot;);
  67. // Closing the PDPageContentStream object
  68. contents.close();
  69. }
  70. document.save(&quot;RemoveImage.pdf&quot;);
  71. document.close();
  72. }
  73. }
  74. Kindly help me with this.
  75. **Also, looking forward for other code review comments about required changes to make this operation properly.** :)
  76. [1]: https://i.stack.imgur.com/VJaec.png
  77. </details>
  78. # 答案1
  79. **得分**: 1
  80. 根据@Tilman Hausherr的建议,以下代码适用于我:
  81. ```java
  82. public static void removeImages(String pdfFile) throws Exception {
  83. PDDocument document = PDDocument.load(new File(pdfFile));
  84. for (PDPage page : document.getPages()) {
  85. PDResources pdResources = page.getResources();
  86. String[] qrCodeCosName = new String[1];
  87. pdResources.getXObjectNames().forEach(propertyName -> {
  88. if (!pdResources.isImageXObject(propertyName)) {
  89. return;
  90. }
  91. PDXObject o;
  92. try {
  93. o = pdResources.getXObject(propertyName);
  94. if (o instanceof PDImageXObject) {
  95. PDImageXObject pdImageXObject = (PDImageXObject) o;
  96. if (pdImageXObject.getMetadata() != null) {
  97. // TO REMOVE FROM RESOURCE
  98. ((COSDictionary) pdResources.getCOSObject().getDictionaryObject(COSName.XOBJECT))
  99. .removeItem(propertyName);
  100. qrCodeCosName[0] = propertyName.getName();
  101. }
  102. }
  103. } catch (IOException e) {
  104. e.printStackTrace();
  105. }
  106. });
  107. PDFStreamParser parser = new PDFStreamParser(page);
  108. parser.parse();
  109. List<Object> tokens = parser.getTokens();
  110. System.out.println("Original tokens size" + tokens.size());
  111. List<Object> newTokens = new ArrayList<Object>();
  112. for (int j = 0; j < tokens.size(); j++) {
  113. Object token = tokens.get(j);
  114. if (token instanceof Operator) {
  115. Operator op = (Operator) token;
  116. // find image - remove it
  117. if (op.getName().equals("Do")) {
  118. COSName cosName = (COSName) tokens.get(j - 1);
  119. if (cosName.getName().equals(qrCodeCosName[0])) {
  120. newTokens.remove(newTokens.size() - 1);
  121. continue;
  122. }
  123. }
  124. newTokens.add(token);
  125. }
  126. System.out.println("tokens size" + newTokens.size());
  127. PDStream newContents = new PDStream(document);
  128. OutputStream out = newContents.createOutputStream();
  129. ContentStreamWriter writer = new ContentStreamWriter(out);
  130. writer.writeTokens(newTokens);
  131. out.close();
  132. page.setContents(newContents);
  133. // ADD OTHER IMAGE
  134. PDImageXObject pdImage = PDImageXObject.createFromFile("D:\\copy\\ind.png", document);
  135. PDPageContentStream contents = new PDPageContentStream(document, page,
  136. PDPageContentStream.AppendMode.PREPEND, true, true);
  137. contents.saveGraphicsState();
  138. // Drawing the image in the PDF document
  139. contents.drawImage(pdImage, 0, 0, 50, 30);
  140. contents.restoreGraphicsState();
  141. System.out.println("Image inserted Successfully.");
  142. // Closing the PDPageContentStream object
  143. contents.close();
  144. }
  145. document.save("RemoveImage.pdf");
  146. document.close();
  147. }
  148. }
英文:

As per @Tilman Hausherr suggestion below code works for me:

  1. public static void removeImages(String pdfFile) throws Exception {
  2. PDDocument document = PDDocument.load(new File(pdfFile));
  3. for (PDPage page : document.getPages()) {
  4. PDResources pdResources = page.getResources();
  5. String[] qrCodeCosName = new String[1];
  6. pdResources.getXObjectNames().forEach(propertyName -&gt; {
  7. if (!pdResources.isImageXObject(propertyName)) {
  8. return;
  9. }
  10. PDXObject o;
  11. try {
  12. o = pdResources.getXObject(propertyName);
  13. if (o instanceof PDImageXObject) {
  14. PDImageXObject pdImageXObject = (PDImageXObject) o;
  15. if (pdImageXObject.getMetadata() != null) {
  16. // TO REMOVE FROM RESOURCE
  17. ((COSDictionary) pdResources.getCOSObject().getDictionaryObject(COSName.XOBJECT))
  18. .removeItem(propertyName);
  19. qrCodeCosName[0] = propertyName.getName();
  20. }
  21. }
  22. } catch (IOException e) {
  23. e.printStackTrace();
  24. }
  25. });
  26. PDFStreamParser parser = new PDFStreamParser(page);
  27. parser.parse();
  28. List&lt;Object&gt; tokens = parser.getTokens();
  29. System.out.println(&quot;Original tokens size&quot; + tokens.size());
  30. List&lt;Object&gt; newTokens = new ArrayList&lt;Object&gt;();
  31. for (int j = 0; j &lt; tokens.size(); j++) {
  32. Object token = tokens.get(j);
  33. if (token instanceof Operator) {
  34. Operator op = (Operator) token;
  35. // find image - remove it
  36. if (op.getName().equals(&quot;Do&quot;)) {
  37. COSName cosName = (COSName) tokens.get(j - 1);
  38. if (cosName.getName().equals(qrCodeCosName[0])) {
  39. newTokens.remove(newTokens.size() - 1);
  40. continue;
  41. }
  42. }
  43. newTokens.add(token);
  44. }
  45. System.out.println(&quot;tokens size&quot; + newTokens.size());
  46. PDStream newContents = new PDStream(document);
  47. OutputStream out = newContents.createOutputStream();
  48. ContentStreamWriter writer = new ContentStreamWriter(out);
  49. writer.writeTokens(newTokens);
  50. out.close();
  51. page.setContents(newContents);
  52. // ADD OTHER IMAGE
  53. PDImageXObject pdImage = PDImageXObject.createFromFile(&quot;D:\\copy\\ind.png&quot;, document);
  54. PDPageContentStream contents = new PDPageContentStream(document, page,
  55. PDPageContentStream.AppendMode.PREPEND, true, true);
  56. contents.saveGraphicsState();
  57. // Drawing the image in the PDF document
  58. contents.drawImage(pdImage, 0, 0, 50, 30);
  59. contents.restoreGraphicsState();
  60. System.out.println(&quot;Image inserted Successfully.&quot;);
  61. // Closing the PDPageContentStream object
  62. contents.close();
  63. }
  64. document.save(&quot;RemoveImage.pdf&quot;);
  65. document.close();
  66. }
  67. }

huangapple
  • 本文由 发表于 2020年10月23日 15:14:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/64495532.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定