2016-10-26 4 views
0

私は、Java 8 Spring BootアプリケーションでPDFBox 2.1.0-SNAPSHOTを使用しています。画像のみのPDF文書。視覚的には、どんなリーダーやブラウザのインラインPDFビューアでもウォーターマークを通して画像を見ることができるので、うまく動作します。PDFBox(2.1.0):IE11から印刷すると、透過テキストウォーターマークが不透明な背景を持つ

しかし、これらの文書をIEから印刷すると、不透明な白い背景がテキストの後ろの画像を覆います。ウォーターマークテキストは透明ですが、テキストの境界ボックスは白です。ここでも、他のすべてのブラウザからの印刷はうまく動作します。 (お奨めは、IEが大好きです。)

ここで私は、各ページに透かしを追加するために使用しているコードだ:

public void watermark(File pdfFile, OutputStream output) throws IOException { 
    try (final InputStream sourceStream = new FileInputStream(pdfFile); 
     final PDDocument document = PDDocument.load(sourceStream)) { 

     for (int pageNumber = 0; pageNumber < document.getNumberOfPages(); pageNumber++) { 
      PDPage currPage = document.getPage(pageNumber); 
      writeWatermarkOnPage(document, currPage); 
     } 
     document.save(output); 
    } 
} 

private void writeWatermarkOnPage(PDDocument document, PDPage page) throws IOException { 
    try (PDPageContentStream contentStream = new PDPageContentStream(
      document, page, PDPageContentStream.AppendMode.APPEND, true, true)) { 

     PDRectangle rect = page.getBBox(); 
     // Set the opacity 
     PDExtendedGraphicsState extendedGraphicsState = new PDExtendedGraphicsState(); 
     extendedGraphicsState.setNonStrokingAlphaConstant(0.3f); 
     contentStream.setGraphicsStateParameters(extendedGraphicsState); 

     // Add the text 
     contentStream.beginText(); 
     contentStream.setFont(PDType1Font.HELVETICA_BOLD, 75); 
     contentStream.setNonStrokingColor(Color.GRAY); 
     AffineTransform at = new AffineTransform(1, 0, 0, 1, 
               rect.getUpperRightX()/4, 
               rect.getUpperRightY()/4); 
     Matrix matrix = new Matrix(at); 
     matrix.rotate(Math.toRadians(45)); 
     contentStream.setTextMatrix(matrix); 
     contentStream.showText("WATERMARK-TEXT"); 
     contentStream.endText(); 
    } 
} 

私はオーバーレイクラスを使用してみましたが、それは同じ結果を持っていました。私は、回転と変換を削除しようとしましたが、それは助けになりませんでした。 nonStrokingAlphaConstant設定を削除した場合にのみ、IEのインラインPDFレンダラーから印刷された不透明な白い背景が消えてしまいますが、テキストは透明ではありません。

テキストの背景が完全に透明でなければならないという文脈の中で、すべてのPDFリーダーに伝えたいことがありますか?ここ

UPDATE

は、例えばPDF Document that shows this behaviorあります。 Windowsでは、&をIEにドロップして印刷するだけで、透かしテキストの白い背景が下の画像を覆い隠します。

IEのPDF created and watermarked with the same code that actually prints just fineの別の例があります。ウォーターマークは白い背景なしで透明です。

壊れた文書はリーガルサイズの画像であり、作業文書はレターサイズです。多分スケーリングに関連する何かが問題を引き起こしているでしょうか?

+0

1)Adobe Readerから印刷すると問題ありませんか? 2)PDFを表示/印刷するためにMSIEで使用されるプログラムは何ですか? –

+0

はい、@Tilman、私はスタンドアロンのAdobe Reader DCから奇妙に印刷しても問題ありません。 MSIEでは、Adobe Readerを使用してPDFを表示/印刷しています。 – arogos

+0

問題が認められるサンプルpdfをご提供ください。 – mkl

答えて

0

透明なPNGをテキストとして追加するのではなく透かしとして使用することで、目標を達成できました。新しい透かし入りのファイルはIEを含むすべてのブラウザから正しく印刷されるようになりました。ここで私は、PDFの各ページにウォーターマークを追加するために使用されるコードは次のとおりです。

private static final String WATERMARK_RESOURCE_PATH = "/watermark/hcro_copy.png"; 

public void watermark(File pdfFile, OutputStream output) throws IOException { 
    try (final InputStream sourceStream = new FileInputStream(pdfFile); 
     final PDDocument document = PDDocument.load(sourceStream) 
    ) { 
     for (int pageNumber = 0; pageNumber < document.getNumberOfPages(); pageNumber++) { 
      PDPage currPage = document.getPage(pageNumber); 
      writeWatermarkWithTransparentImageOnPage(document, currPage); 
     } 
     document.save(output); 
    } 
} 

private void writeWatermarkWithTransparentImageOnPage(PDDocument document, PDPage page) 
     throws IOException { 
    try (PDPageContentStream contentStream = new PDPageContentStream(
      document, page, PDPageContentStream.AppendMode.APPEND, true, true); 
     InputStream watermarkFileStream = getWatermarkFileStream() 
    ) { 
     // Load watermark image 
     BufferedImage image = ImageIO.read(watermarkFileStream); 
     PDImageXObject pdxImage = LosslessFactory.createFromImage(document, image); 

     // Set the opacity 
     PDExtendedGraphicsState extendedGraphicsState = new PDExtendedGraphicsState(); 
     extendedGraphicsState.setNonStrokingAlphaConstant(0.35f); 
     contentStream.setGraphicsStateParameters(extendedGraphicsState); 

     // Center watermark image on page 
     PDRectangle rect = page.getBBox(); 
     int imageX = Math.floorDiv((Math.round(rect.getWidth()) - pdxImage.getWidth()), 2); 
     int imageY = Math.floorDiv((Math.round(rect.getHeight()) - pdxImage.getHeight()), 2); 

     contentStream.drawImage(pdxImage, imageX, imageY); 
    } 
} 

private InputStream getWatermarkFileStream() { 
    try { 
     Resource resource = new ClassPathResource(WATERMARK_RESOURCE_PATH); 
     return resource.getInputStream(); 
    } 
    catch (IOException e) { 
     throw new RuntimeException(e); 
    } 
} 

私はまだテキストのみの回答に開いていると思いますが、これは今私のために動作します。

関連する問題