本文介绍了Itextsharp 7-作为水印的缩放和居中图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几天前,我开始使用itextsharp 7,过去几年中我一直使用itextsharp 5.

I started using itextsharp 7 a few days ago, i used to work with itextsharp 5 for years .

我无法使用itext7在页面中心添加缩放图像作为水印.

I don't manage to add a scaled image at the center of the page as watermark with itext7.

我使用itextsharp 5的代码:

My code with 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示例的代码):

Here is with itextsharp 7 (code based on the itext 7 examples):

   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方法缩放图像.

The image is centered but i dont manage to scale it with the AddImage method.

也许很容易做到,但是我为此感到挣扎.

Maybe it is easily done but i am struggling with this.

任何帮助表示赞赏.

推荐答案

我已将您的示例改编为Java,但这无关紧要,因为重要的是Math:

I have adapted your example to Java, but that shouldn't matter much since it's the Math that is important:

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();
}

这段代码的结果如下:

这完全符合我的期望.

一些解释.

  • 我有一个尺寸为iW x iH的图像mascot.png.
  • 我的页面尺寸为pW x pH.
  • 我想缩放图像以使其占据宽度的50%,因此我创建了一个值0.5f(50%)x``(pW/iW)`的变量f.
  • 我将因子f应用于图像的初始值,得到缩放后的尺寸sW x sH.
  • 我通过减去页面中间的缩放宽度和高度的一半来定义图像(x, y)的偏移量.
  • I have an image mascot.png with dimensions iW x iH.
  • I have pages with dimensions pW x pH.
  • I want to scale the image so that it takes 50% of the width, hence I create a variable f with value 0.5f (50%) x ``(pW / iW)`.
  • I apply the factor f to the initial values of the images, resulting in the scaled dimensions sW x sH.
  • I define an offset for the image (x, y) by subtracting half of the scaled width and height of the middle of the page.

现在,我有了addImage()方法所需的值:over.addImage(img, sW, 0, 0, sH, x, y);

Now I have the values I need for the addImage() method: over.addImage(img, sW, 0, 0, sH, x, y);

注意:您正在将图像添加为内嵌图像.这是一个坏主意,因为它会导致PDF文件过大,尤其是在水印的情况下.通过将图像作为嵌入式图像添加到每页,您可以将图像字节冗余地添加到页面数.最好将图像添加为Image XObject,在这种情况下,无论您使用同一图像多少次,图像字节都只会添加到文档一次.请从addImage()方法的参数中删除true值(在之前之后 PDF,并比较文件大小以了解我的意思).

Note: you were adding the images as an inline image. That's a bad idea because it leads to bloated PDF files, especially in the case of watermarks. By adding an image as an inline image to each page, you add the image bytes redundantly as many times as there are pages. It's much better to add the image as an Image XObject, in which case the image bytes will be added to the document only once, no matter how many times you use that same image. Please remove the true value from the parameters of the addImage() method (make a before and after PDF, and compare the file size to understand what I mean).

这篇关于Itextsharp 7-作为水印的缩放和居中图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 14:05