PDF特にPDFBoxで透かしを追加しようとしています。各ページに画像を表示することはできましたが、PDJpegのように表示されるため、背景の透明度が失われます。それをJPGに変換します。おそらくPDXObjectImageを使用してそれを行う方法があります。
これが私がこれまでに書いたものです:
public static void watermarkPDF(PDDocument pdf) throws IOException
{
// Load watermark
BufferedImage buffered = ImageIO.read(new File("C:\\PDF_Test\\watermark.png"));
PDJpeg watermark = new PDJpeg(pdf, buffered);
// Loop through pages in PDF
List pages = pdf.getDocumentCatalog().getAllPages();
Iterator iter = pages.iterator();
while(iter.hasNext())
{
PDPage page = (PDPage)iter.next();
// Add watermark to individual page
PDPageContentStream stream = new PDPageContentStream(pdf, page, true, false);
stream.drawImage(watermark, 100, 0);
stream.close();
}
try
{
pdf.save("C:\\PDF_Test\\watermarktest.pdf");
}
catch (COSVisitorException e)
{
e.printStackTrace();
}
}
更新された回答(以下のコメンテーターと回答を入力してくれた@okokのおかげで、透かしを入れる簡単な方法を備えたより良いバージョン)
PDFBox 1.8.10以降を使用している場合は、PDFドキュメントに透かしを簡単に追加して、透かしを入れる必要のあるページをより適切に制御できます。透かし画像を含む1ページのPDFドキュメントがあると仮定すると、次のように、透かしを挿入するドキュメントにこれをオーバーレイできます。
1.8.10を使用したサンプルコード
import Java.util.HashMap;
import org.Apache.pdfbox.pdmodel.PDDocument;
import org.Apache.pdfbox.util.Overlay;
public class TestPDF {
public static void main(String[] args) throws Exception{
PDDocument realDoc = PDDocument.load("originaldocument.pdf");
//the above is the document you want to watermark
//for all the pages, you can add overlay guide, indicating watermark the original pages with the watermark document.
HashMap<Integer, String> overlayGuide = new HashMap<Integer, String>();
for(int i=0; i<realDoc.getPageCount(); i++){
overlayGuide.put(i+1, "watermark.pdf");
//watermark.pdf is the document which is a one page PDF with your watermark image in it. Notice here that you can skip pages from being watermarked.
}
Overlay overlay = new Overlay();
overlay.setInputPDF(realDoc);
overlay.setOutputFile("final.pdf");
overlay.setOverlayPosition(Overlay.Position.BACKGROUND);
overlay.overlay(overlayGuide,false);
//final.pdf will have the original PDF with watermarks.
PDFBox 2.0.0リリース候補を使用したサンプル
import Java.io.File;
import Java.util.HashMap;
import org.Apache.pdfbox.multipdf.Overlay;
import org.Apache.pdfbox.pdmodel.PDDocument;
public class TestPDF {
public static void main(String[] args) throws Exception{
PDDocument realDoc = PDDocument.load(new File("originaldocument.pdf"));
//the above is the document you want to watermark
//for all the pages, you can add overlay guide, indicating watermark the original pages with the watermark document.
HashMap<Integer, String> overlayGuide = new HashMap<Integer, String>();
for(int i=0; i<realDoc.getNumberOfPages(); i++){
overlayGuide.put(i+1, "watermark.pdf");
//watermark.pdf is the document which is a one page PDF with your watermark image in it.
//Notice here, you can skip pages from being watermarked.
}
Overlay overlay = new Overlay();
overlay.setInputPDF(realDoc);
overlay.setOutputFile("final.pdf");
overlay.setOverlayPosition(Overlay.Position.BACKGROUND);
overlay.overlay(overlayGuide);
}
}
オーバーレイに新しいパッケージorg.Apache.pdfbox.tools.OverlayPDFを使用する場合は、この方法で実行できます。 (下のポスターありがとう)
String[] overlayArgs = {"C:/Examples/foreground.pdf", "C:/Examples/background.pdf", "C:/Examples/resulting.pdf"};
OverlayPDF.main(overlayArgs);
System.out.println("Overlay finished.");
OLD ANSWER非効率的な方法であり、推奨されません。
さて、OPはPDFBoxでそれを行う方法を尋ねました、最初の答えはiTextを使用した例のように見えます。 PDFBoxで透かしを作成するのは本当に簡単です。秘訣は、透かし画像を含む空のPDFドキュメントを用意することです。次に、ウォーターマークを追加するドキュメントにこのウォーターマークドキュメントをオーバーレイするだけです。
PDDocument watermarkDoc = PDDocument.load("watermark.pdf");
//Assuming your empty document with watermark image in it.
PDDocument realDoc = PDDocument.load("document-to-be-watermarked.pdf");
//Let's say this is your document that you want to watermark. For example sake, I am opening a new one, you would already have a reference to PDDocument if you are creating one
Overlay overlay = new Overlay();
overlay.overlay(realDoc,watermarkDoc);
watermarkDoc.save("document-now-watermarked.pdf");
注意:両方のドキュメントのページ数が一致していることを確認する必要があります。そうしないと、ページ数が最も少ないドキュメントと一致するページ数のドキュメントになってしまいます。透かしドキュメントを操作して、ドキュメントに一致するようにページを複製できます。
お役に立てれば。!
次のコードを作成して、(透明な)画像(jpg、png、gif)をpdfboxを使用してpdfページに追加します。
/**
* Draw an image to the specified coordinates onto a single page. <br>
* Also scaled the image with the specified factor.
*
* @author Nick Russler
* @param document PDF document the image should be written to.
* @param pdfpage Page number of the page in which the image should be written to.
* @param x X coordinate on the page where the left bottom corner of the image should be located. Regard that 0 is the left bottom of the pdf page.
* @param y Y coordinate on the page where the left bottom corner of the image should be located.
* @param scale Factor used to resize the image.
* @param imageFilePath Filepath of the image that is written to the PDF.
* @throws IOException
*/
public static void addImageToPage(PDDocument document, int pdfpage, int x, int y, float scale, String imageFilePath) throws IOException {
// Convert the image to TYPE_4BYTE_ABGR so PDFBox won't throw exceptions (e.g. for transparent png's).
BufferedImage tmp_image = ImageIO.read(new File(imageFilePath));
BufferedImage image = new BufferedImage(tmp_image.getWidth(), tmp_image.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
image.createGraphics().drawRenderedImage(tmp_image, null);
PDXObjectImage ximage = new PDPixelMap(document, image);
PDPage page = (PDPage)document.getDocumentCatalog().getAllPages().get(pdfpage);
PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true);
contentStream.drawXObject(ximage, x, y, ximage.getWidth()*scale, ximage.getHeight()*scale);
contentStream.close();
}
例:
public static void main(String[] args) throws Exception {
String pdfFilePath = "C:/Users/Nick/Desktop/pdf-test.pdf";
String signatureImagePath = "C:/Users/Nick/Desktop/signature.png";
int page = 0;
PDDocument document = PDDocument.load(pdfFilePath);
addImageToPage(document, page, 0, 0, 0.5f, signatureImagePath);
document.save("C:/Users/Nick/Desktop/pdf-test-neu.pdf");
}
これは、jdk 1.7およびbcmail-jdk16-140.jar、bcprov-jdk16-140.jar、commons-logging-1.1.3.jar、fontbox-1.8.3.jar、jempbox-1.8.3.jar、およびpdfbox-1.8.3.jar。
@Androidman: https://stackoverflow.com/a/9382212/780297 への追加
PDFBoxのバージョンごとに多くのメソッドが削除されているようです。そのため、コードはPDFBox2.0.7では機能しません。
_Overlay overlay = new Overlay();
overlay.setInputPDF(realDoc);
// ** The method setOutputFile(String) is undefined for the type Overlay **
overlay.setOutputFile("final.pdf")
_
代わりに、void org.Apache.pdfbox.pdmodel.PDDocument.save(String fileName)
を使用してください。
_PDDocument realDoc = PDDocument.load(new File("originaldocument.pdf"));
//the above is the document you want to watermark
//for all the pages, you can add overlay guide, indicating watermark the original pages with the watermark document.
HashMap<Integer, String> overlayGuide = new HashMap<Integer, String>();
for(int i=0; i<realDoc.getNumberOfPages(); i++){
overlayGuide.put(i+1, "watermark.pdf");
//watermark.pdf is the document which is a one page PDF with your watermark image in it.
//Notice here, you can skip pages from being watermarked.
}
Overlay overlay = new Overlay();
overlay.setInputPDF(realDoc);
overlay.overlay(overlayGuide).save("final.pdf");
overlay.close();
_
編集:オーバーレイに_org.Apache.pdfbox.tools.OverlayPDF
_を使用していますが、正常に機能します。コードは次のようになります。
_String[] overlayArgs = {"C:/Examples/foreground.pdf", "C:/Examples/background.pdf", "C:/Examples/resulting.pdf"};
OverlayPDF.main(overlayArgs);
System.out.println("Overlay finished.");
_
コメントを追加するのに十分な評判がなかったので、これを新しい回答に追加するのが適切だと思いました。
Utilパッケージ内に別のOverlayクラスがあり、ソースドキュメントと同じページ数のPDFを作成してから、オーバーレイを実行する手間を省くことができます。
その使用法を理解するには、pdfboxのソースコード、特にOverlayPDFクラスを見てください。