几天前我开始使用itextsharp 7,过去几年我一直使用itextsharp 5。
我无法使用itext7在页面中心添加缩放图像作为水印。
我使用itextsharp 5的代码:
using (PdfStamper pdfStamper = new PdfStamper(pdfReader, memoryStream))
{
for (int pageIndex = 1; pageIndex <= pdfReader.NumberOfPages; pageIndex++)
{
pdfStamper.FormFlattening = false;
iTextSharp.text.Rectangle pageRectangle = pdfReader.GetPageSizeWithRotation(pageIndex);
PdfContentByte pdfData = pdfStamper.GetOverContent(pageIndex);
PdfGState graphicsState = new PdfGState();
graphicsState.FillOpacity = 0.4F;
pdfData.SetGState(graphicsState);
pdfData.BeginText();
Image imageWM = Image.GetInstance(image_WM_Path);
float width = pageRectangle.Width;
float height = pageRectangle.Height;
//scale image
imageWM.ScaleToFit(width / 3, height / 3);
//center image
imageWM.SetAbsolutePosition(width / 2 - imageWM.ScaledWidth / 2, height / 2 - imageWM.ScaledHeight / 2);
pdfData.AddImage(imageWM);
pdfData.EndText();
}
pdfStamper.Close();
return memoryStream.ToArray();
}
此处是itextsharp 7(基于itext 7示例的代码):
PdfDocument pdfDoc = new PdfDocument(new PdfReader(sourceFile), new PdfWriter(destinationPath));
Document document = new Document(pdfDoc);
PdfCanvas over;
PdfExtGState gs1 = new PdfExtGState();
gs1.SetFillOpacity(0.5f);
int n = pdfDoc.GetNumberOfPages();
Rectangle pagesize;
float x, y;
ImageData img = ImageDataFactory.Create(image_WM_Path);
float w = img.GetWidth();
float h = img.GetHeight();
for (int i = 1; i <= n; i++)
{
PdfPage pdfPage = pdfDoc.GetPage(i);
pagesize = pdfDoc.GetPage(i).GetPageSize();
pdfPage.SetIgnorePageRotationForContent(true);
x = (pagesize.GetLeft() + pagesize.GetRight()) / 2;
y = (pagesize.GetTop() + pagesize.GetBottom()) / 2;
over = new PdfCanvas(pdfDoc.GetPage(i));
over.SaveState();
over.SetExtGState(gs1);
over.AddImage(img, w, 0, 0, h, x - (w / 2), y - (h / 2), true);
over.RestoreState();
}
document.Close();
pdfDoc.Close();
图像居中,但我无法使用AddImage方法缩放图像。
也许很容易做到,但是我为此感到困惑。
任何帮助表示赞赏。
答案 0 :(得分:0)
我已经使您的示例适应Java,但这没关系,因为重要的是数学:
public static final String SRC = "src/main/resources/pdfs/hello.pdf";
public static final String DEST = "results/text/watermark.pdf";
public static final String IMG = "src/main/resources/img/mascot.png";
public static void main(String[] args) throws IOException {
File file = new File(DEST);
file.getParentFile().mkdirs();
new Watermark().createPdf(SRC, DEST);
}
public void createPdf(String src, String dest) throws IOException {
PdfDocument pdfDoc = new PdfDocument(
new PdfReader(src), new PdfWriter(dest));
Document document = new Document(pdfDoc);
PdfCanvas over;
PdfExtGState gs1 = new PdfExtGState();
gs1.setFillOpacity(0.5f);
int n = pdfDoc.getNumberOfPages();
Rectangle pagesize;
ImageData img = ImageDataFactory.create(IMG);
float iW = img.getWidth();
float iH = img.getHeight();
float pW, pH, sW, sH, f, x, y;
for (int i = 1; i <= n; i++)
{
PdfPage pdfPage = pdfDoc.getPage(i);
pagesize = pdfPage.getPageSize();
pW = pagesize.getWidth();
pH = pagesize.getHeight();
f = (pW / iW) * 0.5f;
sW = iW * f;
sH = iH * f;
x = pagesize.getLeft() + (pW / 2) - (sW / 2);
y = pagesize.getBottom() + (pH / 2) - (sH / 2);
over = new PdfCanvas(pdfDoc.getPage(i));
over.saveState();
over.setExtGState(gs1);
over.addImage(img, sW, 0, 0, sH, x, y);
over.restoreState();
}
document.close();
pdfDoc.close();
}
这段代码的结果如下:
这完全符合我的期望。
一些解释。
mascot.png
,尺寸为iW
x iH
。pW
x pH
。f
,其值为0.5f
(50%)x``(pW / iW)`。 f
应用于图像的初始值,得出缩放后的尺寸sW
x sH
。(x, y)
的偏移量。现在,我有了addImage()
方法所需的值:over.addImage(img, sW, 0, 0, sH, x, y);
注意:您正在将图像添加为内嵌图像。这是一个坏主意,因为它会导致PDF文件过大,尤其是在水印的情况下。通过将图像作为嵌入式图像添加到每个页面,您可以将图像字节冗余地添加到页面数。最好将图像添加为Image XObject,在这种情况下,无论您使用同一图像多少次,图像字节都只会添加到文档一次。请从true
方法的参数中删除addImage()
值(在之前和之后 PDF,并比较文件大小以了解什么)我的意思是。)