Itextsharp 7 - 缩放并居中的图像作为水印

标签 itext watermark itext7

几天前我开始使用 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 方法缩放它。

也许这很容易完成,但我正在努力解决这个问题。

感谢任何帮助。

最佳答案

我已将您的示例改编为 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();
}

此代码的结果如下所示:

enter image description here

这看起来正是我所期望的。

一些解释。

  • 我有一个图像 mascot.png,尺寸为 iW x iH
  • 我的页面尺寸为 pW x pH
  • 我想缩放图像,使其占据宽度的 50%,因此我创建了一个变量 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,在这种情况下,无论您使用同一图像多少次,图像字节都只会添加到文档中一次。请从 addImage() 方法的参数中删除 true 值(制作之前之后 PDF,并比较文件大小以理解我的意思)。

关于Itextsharp 7 - 缩放并居中的图像作为水印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51176267/

相关文章:

c# - 在c#中将iTextsharp 5.5.4升级到5.5.7

java - 将背景图像设置到标题单元格

java - 如何扩展PDF页面大小以添加水印?

android - 如何将图像放在 TextView 中的文本下方

java - iText 7 : Set text field once even if it exists multiple times with the same name

java - iText 7 无边框表格(无边框)

itext - 使用 iText 和 Java 保存 tiff CCITTFaxDecode(来自 PDF 页面)

c# - "File does not begin with ' %PDF- '."尝试加载 PDF 时出错 - ASP.NET MVC

java - 如何为 keystore 创建属性文件?

php - 下载图片自动添加水印