C# iText7:如何忽略PDF页面旋转

C# iText7:如何忽略PDF页面旋转,c#,pdf,itext,itext7,C#,Pdf,Itext,Itext7,我已经为这个问题挣扎了很长时间了。我只是想用iText7.NET实现一个戳记功能。问题首先来自透明度。如果我使用图像(尝试使用透明png),pdf会被压印,但背景是黑色,而不是透明的: 出于兴趣,相关代码如下所示: Rectangle location = new Rectangle(crop.GetLeft(),crop.GetBottom(),iWidth/4,iHeight/4); PdfStampAnnotation stamp = new PdfStampAnnotation(lo

我已经为这个问题挣扎了很长时间了。我只是想用iText7.NET实现一个戳记功能。问题首先来自透明度。如果我使用图像(尝试使用透明png),pdf会被压印,但背景是黑色,而不是透明的:

出于兴趣,相关代码如下所示:

Rectangle location = new Rectangle(crop.GetLeft(),crop.GetBottom(),iWidth/4,iHeight/4);

PdfStampAnnotation stamp = new PdfStampAnnotation(location).SetStampName(new PdfName("Logo"));

PdfFormXObject xObj = new PdfFormXObject(new Rectangle(iWidth, iHeight));
PdfCanvas canvas = new PdfCanvas(xObj, pdfDoc);
canvas.AddImage(img, 0, 0,iWidth, false);
stamp.SetNormalAppearance(xObj.GetPdfObject());

stamp.SetFlags(PdfAnnotation.PRINT);

pdfDoc.GetFirstPage().AddAnnotation(stamp);
pdfDoc.Close();
// Document to be edited and documented to be merged in
PdfDocument newDoc = new PdfDocument(reader, writer);
PdfDocument srcDoc = new PdfDocument(new PdfReader(stampsrc));

// CropBox And Dimensions
Rectangle crop = newDoc.GetFirstPage().GetCropBox();
float width = crop.GetWidth();
float height = crop.GetHeight();

// Create FormXObject and Canvas
PdfFormXObject page = srcDoc.GetPage(1).CopyAsFormXObject(newDoc);
//Extract Page Dimensions
float xWidth = srcDoc.GetFirstPage().GetCropBox().GetWidth();
float xHeight = srcDoc.GetFirstPage().GetCropBox().GetHeight();

Rectangle location = new Rectangle(crop.GetLeft(), crop.GetBottom(), xWidth , xHeight );

Debug.WriteLine(location.GetWidth());

PdfStampAnnotation stamp = new PdfStampAnnotation(location).SetStampName(new PdfName("Logo"));
PdfCanvas canvas = new PdfCanvas(newDoc.GetFirstPage().NewContentStreamBefore(), newDoc.GetFirstPage().GetResources(), newDoc);

// canvas.AddXObject(page,location.GetLeft(),location.GetBottom(),page.GetWidth());
stamp.SetNormalAppearance(page.GetPdfObject());
stamp.SetFlags(PdfAnnotation.PRINT);
newDoc.GetFirstPage().AddAnnotation(stamp);

srcDoc.Close();
newDoc.Close();
为了解决这个问题,我尝试模仿Adobe在邮票插入方面的做法-将邮票PDF合并到现有文档中。事后看来,结果非常好,但事实证明,一旦您将戳记文档复制为PdfFormXObject,合并过程就会考虑旋转——因此,恰好具有非零旋转值(通常由于扫描)的戳记文档的方向是错误的(或由于翻转的高宽比而过度拉伸)

关联的代码如下所示:

Rectangle location = new Rectangle(crop.GetLeft(),crop.GetBottom(),iWidth/4,iHeight/4);

PdfStampAnnotation stamp = new PdfStampAnnotation(location).SetStampName(new PdfName("Logo"));

PdfFormXObject xObj = new PdfFormXObject(new Rectangle(iWidth, iHeight));
PdfCanvas canvas = new PdfCanvas(xObj, pdfDoc);
canvas.AddImage(img, 0, 0,iWidth, false);
stamp.SetNormalAppearance(xObj.GetPdfObject());

stamp.SetFlags(PdfAnnotation.PRINT);

pdfDoc.GetFirstPage().AddAnnotation(stamp);
pdfDoc.Close();
// Document to be edited and documented to be merged in
PdfDocument newDoc = new PdfDocument(reader, writer);
PdfDocument srcDoc = new PdfDocument(new PdfReader(stampsrc));

// CropBox And Dimensions
Rectangle crop = newDoc.GetFirstPage().GetCropBox();
float width = crop.GetWidth();
float height = crop.GetHeight();

// Create FormXObject and Canvas
PdfFormXObject page = srcDoc.GetPage(1).CopyAsFormXObject(newDoc);
//Extract Page Dimensions
float xWidth = srcDoc.GetFirstPage().GetCropBox().GetWidth();
float xHeight = srcDoc.GetFirstPage().GetCropBox().GetHeight();

Rectangle location = new Rectangle(crop.GetLeft(), crop.GetBottom(), xWidth , xHeight );

Debug.WriteLine(location.GetWidth());

PdfStampAnnotation stamp = new PdfStampAnnotation(location).SetStampName(new PdfName("Logo"));
PdfCanvas canvas = new PdfCanvas(newDoc.GetFirstPage().NewContentStreamBefore(), newDoc.GetFirstPage().GetResources(), newDoc);

// canvas.AddXObject(page,location.GetLeft(),location.GetBottom(),page.GetWidth());
stamp.SetNormalAppearance(page.GetPdfObject());
stamp.SetFlags(PdfAnnotation.PRINT);
newDoc.GetFirstPage().AddAnnotation(stamp);

srcDoc.Close();
newDoc.Close();
另一种方法涉及使用CopyPageTo方法,但没有理想的结果,因为我无法将其与戳记关联,也不包含透明度。因此,可以看出,我在尝试解决两个问题中的一个问题之间进退两难。要么我设法找到一种方法,使我的图像背景保持透明,而不必担心关于旋转,或者简单地抵消合并页面的旋转(更可取)

此外,我一直在探索其他选项,例如使用仿射变换ConcatMatrix方法进行较低级别的操作-我还不太熟悉它们,但它似乎不直接适用于我的冲压场景?我使用了值为(0-1 0 1)的ConcatMatrix我认为这相当于一个90度的旋转,但我的图章就消失了。我相信最后一对数字是不正确的-但同样,没有完全的理解,所以我不能提出索赔

我尝试过的另一件事(但不清楚理解)是对任一文档的setIgnorePageRotationForContent方法进行修改,以查看它是否影响放置。但是,将其设置为true或false不会改变结果

有什么进一步的建议吗?这个问题真的像我说的那么难吗?我找不到任何直接解决这个问题的在线讨论


提前感谢

添加透明图像的代码非常有效,应该适用于大多数PNG图像

如果由于某种原因无法工作,您可以通过以下方式显式设置图像掩码:

// Circle mask
byte circledata[] = {(byte) 0x3c, (byte) 0x7e, (byte) 0xff,
            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7e,
            (byte) 0x3c};
ImageData mask = ImageDataFactory.Create(8, 8, 1, 1, circledata, null);
mask.MakeMask();
mask.SetInverted(true);
img.SetImageMask(mask);

PdfCanvas canvas = new PdfCanvas(xObj, pdfDoc);
canvas.AddImage(img, 0, 0, iWidth, false);
您也可以从磁盘加载遮罩。只需创建一个与邮票原始图像尺寸相同的图像,并在该遮罩图像中提供透明度级别。然后,您可以加载遮罩并以类似于上述方式将其设置为图像:

ImageData mask = ImageDataFactory.create(MASK_PATH);
mask.MakeMask();
img.SetImageMask(mask);

有关更多详细信息,请参见示例。

您能分享您尝试第一种方法的图像吗?该方法总体上是正确的,至少对图像是有效的。@AlexeySubach我做了……正如我所述,我的问题不是旋转,而是透明度。图像不包含旋转信息,因此像预期的那样标记d、 但是我尝试将图像变为透明的背景变为漆黑(如上面第一张图片所示).我明白。我的意思是,我引用的图像是一个透明的图像,它可以正常工作,没有黑色。@AlexeySubach哇,如果它是真的,那真的可以救我。我不能真正共享该图像,因为它属于更高的权威,可能是机密的。但是我想从你那里了解更多。你使用了什么图像格式使用。您是否将其保留为PNG格式?您是否最终使用了某种掩码?或者您是否调用了我提供的方法之外的任何其他方法?我可以告诉您的是,我是如何准备图像的。最初,我从Adobe将其保存为JPEG格式。显然,结果是不透明的,因此,我使用Paint.NET对其进行了编辑,并删除了背景并保存到PNG。我只使用了你的代码,其他什么都没有。这应该是开箱即用的,但是在你的特定PNG图像中可能有一些特殊的细节。因为你不能提供它来进行分析,我已经写了一个关于如何设置你自己的自定义图像掩码以使图像最终变得透明的答案。