如何使用 itext(itextsharp) 将 MediaBox 移动到 0.0

How move MediaBox to 0.0 with itext(itextsharp)

我的PDF文件的MediaBox坐标是(-8,-8),现在我想设置成(0,0)。

我试过直接设置,但是文件内容被偏移了。 所以我想更改 MediaBox 坐标并移动内容。 这是 itextshare 代码 (c#)。我很高兴能够用 Java itext 解决它。

using (PdfReader pdfReader = new PdfReader(@"MediaBoxZero.pdf"))
{
    using (PdfStamper stamper = new PdfStamper(pdfReader, new FileStream(@"MediaBoxZero_Result.pdf", FileMode.Create)))
    {
        var mediaBox = pdfReader.GetBoxSize(1, "media");

        PdfArray mediaBoxN = new PdfArray();
        mediaBoxN.Add(new float[] { 0, 0, mediaBox.Width, mediaBox.Height });

        for (int curPageNum = 1; curPageNum <= pdfReader.NumberOfPages; ++curPageNum)
        {
            PdfDictionary pagedict = pdfReader.GetPageN(curPageNum);
            pagedict.Put(PdfName.MEDIABOX, mediaBoxN);
        }
    }
}

我尝试了仿射变换,但没有用。仿射变换应该只在生成新的 PDF 时有效,而我想编辑现有的 PDF。

        using (PdfReader pdfReader = new PdfReader(@"MediaBoxZero.pdf"))
        {
            using (PdfStamper stamper = new PdfStamper(pdfReader, new FileStream(@"MediaBoxZero_Result.pdf", FileMode.Create)))
            {
                PdfContentByte pb = stamper.GetOverContent(1);
                AffineTransform at = new AffineTransform();
                at.Translate(100,0);
                pb.Transform(at);
                pb.ConcatCTM(at);
                //var mediaBox = pdfReader.GetBoxSize(1, "media");

                //PdfArray mediaBoxN = new PdfArray();
                //mediaBoxN.Add(new float[] { 0, 0, mediaBox.Width, mediaBox.Height });

                //for (int curPageNum = 1; curPageNum <= pdfReader.NumberOfPages; ++curPageNum)
                //{
                //    PdfDictionary pagedict = pdfReader.GetPageN(curPageNum);
                //    foreach (var item in pagedict.GetEnumerator())
                //    {

                //    }
                //    pagedict.Put(PdfName.MEDIABOX, mediaBoxN);
                //}
            }
        }
    }

您可以像这样使用 iTextSharp 移动 页面内容 以匹配 MediaBox 更改:

using (PdfReader pdfReader = new PdfReader(SOURCE_PDF))
{
    for (int i = 1; i <= pdfReader.NumberOfPages; i++)
    {
        Rectangle mediaBox = pdfReader.GetPageSize(i);
        if (mediaBox.Left == 0 && mediaBox.Bottom == 0)
            continue;

        PdfDictionary pageDict = pdfReader.GetPageN(i);
        pageDict.Put(PdfName.MEDIABOX, new PdfArray { new PdfNumber(0), new PdfNumber(0),
            new PdfNumber(mediaBox.Width), new PdfNumber(mediaBox.Height) });
        Rectangle cropBox = pdfReader.GetBoxSize(i, "crop");
        if (cropBox != null)
        {
            pageDict.Put(PdfName.CROPBOX, new PdfArray { new PdfNumber(cropBox.Left - mediaBox.Left),
                new PdfNumber(cropBox.Bottom-mediaBox.Bottom), new PdfNumber(cropBox.Right - mediaBox.Left),
                new PdfNumber(cropBox.Top - mediaBox.Bottom) });
        }
        using (MemoryStream stream = new MemoryStream())
        {
            string translation = String.Format(CultureInfo.InvariantCulture, "1 0 0 1 {0} {1} cm\n", -mediaBox.Left, -mediaBox.Bottom);
            byte[] translationBytes = Encoding.ASCII.GetBytes(translation);
            stream.Write(translationBytes, 0, translationBytes.Length);

            byte[] contentBytes = pdfReader.GetPageContent(i);
            stream.Write(contentBytes, 0, contentBytes.Length);
            pdfReader.SetPageContent(i, stream.ToArray());
        }
    }

    using (FileStream fileStream = new FileStream(@"MediaBox-normalized.pdf", FileMode.Create))
    using (PdfStamper pdfStamper = new PdfStamper(pdfReader, fileStream))
    {
    }
}

一些备注:

  • 您不能简单地操作相应页面的 UnderContent,因为 iText 试图阻止那里的图形状态更改(如当前转换矩阵的更改)渗透到现有内容。因此,这里我们在字节级别上更新页面内容。

  • 代码会更新 CropBox(如果已设置)和 MediaBox。严格来说,它还应该更新 PDF 页面已知的其他框。

  • 代码忽略注释。如果您的 PDF 有注释,您还必须在用户空间坐标中移动注释 Rects 和其他注释属性,例如 QuadPoints顶点