顶部的 iText 标记图像并不总是有效
iText stamp image on top not always working
我正在使用 iTextSharp 在 PDF 的每一页上放置图像和一些文本。这对某些 PDF 非常有效,但对其他 PDF 无效。奇怪的是,它不适用于我使用 Word 2010 的 'Save as pdf' 函数创建的 PDF。我使用 GetOverContent,它应该将所有内容放在最前面。
使用 Acrobat,我可以看到我的图层已添加。所以它一定在某处的文字文字下面。
如何为邮票设置 z-index?
有没有一种方法(工具)可以清楚地看到 PDF 中有哪些对象?我发现 Acrobat 在这方面并不是很有帮助,但也许我需要培训 ;-)
示例无法使用 PDF here。 (link 已更新)
戳这里的代码,PDF来自数据库,存入数据库:
Protected Sub cbTekening_Callback(source As Object, e As DevExpress.Web.CallbackEventArgs) Handles cbTekening.Callback
Dim document As New iTextSharp.text.Document()
Dim intTekID As Integer
Try
Dim fieldValues As List(Of Object) = gridTekeningen.GetSelectedFieldValues(New String() {"TekeningID"})
For Each item As Object In fieldValues
Using ms As MemoryStream = New MemoryStream()
intTekID = item
Dim pdfr = New PdfReader(GetPDFFromDatabase(intTekID).ToArray())
Dim pdfs As New iTextSharp.text.pdf.PdfStamper(pdfr, ms)
Dim image__1 As iTextSharp.text.Image = iTextSharp.text.Image.GetInstance(New System.Uri(Session("ORG_Website") & Session("ORG_Tekeninglogo")))
Dim image__2 As iTextSharp.text.Image = iTextSharp.text.Image.GetInstance(New System.Uri(Session("ORG_Website") & "Images/contactid_" & Session("ContactID") & ".png"))
Dim rect As Rectangle
Dim PageCount As Integer = pdfr.NumberOfPages
Dim content As iTextSharp.text.pdf.PdfContentByte
For x = 1 To PageCount
rect = pdfr.GetPageSize(x)
content = pdfs.GetOverContent(x)
image__1.SetAbsolutePosition(50.0F, 50.0F)
image__1.ScalePercent(30.0F, 30.0F)
image__2.SetAbsolutePosition(100.0F, 100.0F)
image__2.ScalePercent(30.0F, 30.0F)
Content.AddImage(image__1)
Content.AddImage(image__2)
Dim layer As New PdfLayer("Goedkeurlaag" & x.ToString, pdfs.Writer)
'Tell the cb that the next commands should be "bound" to this new layer
Content.BeginLayer(layer)
Content.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 20)
Dim strWatermerkText1 As String = Session("ORG_Tekeningtekst")
Dim strWatermerkText2 As String = Format(Now, "dd-MM-yyyy")
Dim strWatermerkText3 As String = Session("VolNaam")
Content.SetColorFill(BaseColor.RED)
Content.BeginText()
Content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText3, 60, 160, 0.0F)
Content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText2, 60, 185, 0.0F)
Content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText1, 60, 210, 0.0F)
Content.EndText()
'// Close the layer
Content.EndLayer()
Next
pdfs.Close()
StoreToDatabase(ms, intTekID)
End Using
Next item
imgPubliceerTekening.ClientVisible = False
gridTekeningen.DataBind()
Catch ex As Exception
End Try
End Sub
使其可运行
我通过删除所有数据库和会话对象访问使您的示例独立且可运行。此外,我将它翻译成 C#,这对我来说更自然。作为图像,我使用了我们各自的 Whosebug 头像,作为文本,您的代码从中导出字符串值的会话对象键或格式字符串:
void AddStamps(string OrigFile, string ResultFile)
{
Document document = new Document();
using (MemoryStream ms = new MemoryStream())
{
PdfReader pdfr = new PdfReader(OrigFile);
PdfStamper pdfs = new PdfStamper(pdfr, ms);
Image image__1 = Image.GetInstance(new System.Uri("https://www.gravatar.com/avatar/6bc6e4a08a5683b6f4ef8a8eb5117114?s=48&d=identicon&r=PG"));
Image image__2 = Image.GetInstance(new System.Uri("https://www.gravatar.com/avatar/53d3aae5c986ca57f01016f5e0be82de?s=32&d=identicon&r=PG&f=1"));
Rectangle rect;
int PageCount = pdfr.NumberOfPages;
PdfContentByte content;
for (int x = 1; x <= PageCount; x++)
{
rect = pdfr.GetPageSize(x);
content = pdfs.GetOverContent(x);
image__1.SetAbsolutePosition(50.0F, 50.0F);
image__1.ScalePercent(30.0F, 30.0F);
image__2.SetAbsolutePosition(100.0F, 100.0F);
image__2.ScalePercent(30.0F, 30.0F);
content.AddImage(image__1);
content.AddImage(image__2);
PdfLayer layer = new PdfLayer("Goedkeurlaag", pdfs.Writer);
content.BeginLayer(layer);
content.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 20);
String strWatermerkText1 = "ORG_Tekeningtekst";
String strWatermerkText2 = "dd-MM-yyyy";
String strWatermerkText3 = "VolNaam";
content.SetColorFill(BaseColor.RED);
content.BeginText();
content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText3, 60, 160, 0.0F);
content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText2, 60, 185, 0.0F);
content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText1, 60, 210, 0.0F);
content.EndText();
content.EndLayer();
}
pdfs.Close();
File.WriteAllBytes(ResultFile, ms.ToArray());
}
}
运行它
将此方法应用于您的 sample file 结果如下所示:
即在每一页上都清晰可见以下标记:
因此
由于您的示例文档上的图章清晰可见,并且此处 VB 到 C# 的翻译相当忠实,因此问题是由您未提及的某些因素引起的,例如
发生一些异常(可能是在数据库访问期间或由于数据库或会话返回的某些 null
值),您使用
忽略了这些异常
Catch ex As Exception
End Try
空捕获块。
你的图片是完全透明的,你的文字是空的。
一般
So it must be under the word text somewhere.
如果您向 pdfs.GetOverContent(x)
添加内容,它会添加到该页面的现有内容之后,并且由于 PDF 不知道 z 轴,因此以后绘制的任何内容都会覆盖之前绘制的内容。您的新内容只能被
覆盖
- 稍后添加更新的内容或
- 注释内容,因为按规范的所有注释都在所有常规内容之上。
(当然也可以离屏...)
查看新示例文档
同时,OP 提供了一个不同的示例文档,并且将上面的代码应用于它确实不会产生可见的标记。
但是原因上面已经提示了:
Or, of course, it can be off-screen...
OP 的代码隐含地假定坐标系原点位于页面的左下角。虽然这种情况经常发生,但并非必须如此!
OP 的代码已经获取了页面的媒体框:
rect = pdfr.GetPageSize(x)
检查手头文件的媒体框,左下角是(0, -836.64001),右上角是(1207.68005, 0)。因此,原点位于左上角,OP 使用的所有坐标都在可见页面上方 .
如果将上面 C# 代码中的相应行替换为:
image__1.SetAbsolutePosition(rect.Left + 50.0F, rect.Bottom + 50.0F);
...
image__2.SetAbsolutePosition(rect.Left + 100.0F, rect.Bottom + 100.0F);
...
content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText3, rect.Left + 60, rect.Bottom + 160, 0.0F);
content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText2, rect.Left + 60, rect.Bottom + 185, 0.0F);
content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText1, rect.Left + 60, rect.Bottom + 210, 0.0F);
再次获得想要的邮票:
我正在使用 iTextSharp 在 PDF 的每一页上放置图像和一些文本。这对某些 PDF 非常有效,但对其他 PDF 无效。奇怪的是,它不适用于我使用 Word 2010 的 'Save as pdf' 函数创建的 PDF。我使用 GetOverContent,它应该将所有内容放在最前面。
使用 Acrobat,我可以看到我的图层已添加。所以它一定在某处的文字文字下面。
如何为邮票设置 z-index?
有没有一种方法(工具)可以清楚地看到 PDF 中有哪些对象?我发现 Acrobat 在这方面并不是很有帮助,但也许我需要培训 ;-)
示例无法使用 PDF here。 (link 已更新)
戳这里的代码,PDF来自数据库,存入数据库:
Protected Sub cbTekening_Callback(source As Object, e As DevExpress.Web.CallbackEventArgs) Handles cbTekening.Callback
Dim document As New iTextSharp.text.Document()
Dim intTekID As Integer
Try
Dim fieldValues As List(Of Object) = gridTekeningen.GetSelectedFieldValues(New String() {"TekeningID"})
For Each item As Object In fieldValues
Using ms As MemoryStream = New MemoryStream()
intTekID = item
Dim pdfr = New PdfReader(GetPDFFromDatabase(intTekID).ToArray())
Dim pdfs As New iTextSharp.text.pdf.PdfStamper(pdfr, ms)
Dim image__1 As iTextSharp.text.Image = iTextSharp.text.Image.GetInstance(New System.Uri(Session("ORG_Website") & Session("ORG_Tekeninglogo")))
Dim image__2 As iTextSharp.text.Image = iTextSharp.text.Image.GetInstance(New System.Uri(Session("ORG_Website") & "Images/contactid_" & Session("ContactID") & ".png"))
Dim rect As Rectangle
Dim PageCount As Integer = pdfr.NumberOfPages
Dim content As iTextSharp.text.pdf.PdfContentByte
For x = 1 To PageCount
rect = pdfr.GetPageSize(x)
content = pdfs.GetOverContent(x)
image__1.SetAbsolutePosition(50.0F, 50.0F)
image__1.ScalePercent(30.0F, 30.0F)
image__2.SetAbsolutePosition(100.0F, 100.0F)
image__2.ScalePercent(30.0F, 30.0F)
Content.AddImage(image__1)
Content.AddImage(image__2)
Dim layer As New PdfLayer("Goedkeurlaag" & x.ToString, pdfs.Writer)
'Tell the cb that the next commands should be "bound" to this new layer
Content.BeginLayer(layer)
Content.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 20)
Dim strWatermerkText1 As String = Session("ORG_Tekeningtekst")
Dim strWatermerkText2 As String = Format(Now, "dd-MM-yyyy")
Dim strWatermerkText3 As String = Session("VolNaam")
Content.SetColorFill(BaseColor.RED)
Content.BeginText()
Content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText3, 60, 160, 0.0F)
Content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText2, 60, 185, 0.0F)
Content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText1, 60, 210, 0.0F)
Content.EndText()
'// Close the layer
Content.EndLayer()
Next
pdfs.Close()
StoreToDatabase(ms, intTekID)
End Using
Next item
imgPubliceerTekening.ClientVisible = False
gridTekeningen.DataBind()
Catch ex As Exception
End Try
End Sub
使其可运行
我通过删除所有数据库和会话对象访问使您的示例独立且可运行。此外,我将它翻译成 C#,这对我来说更自然。作为图像,我使用了我们各自的 Whosebug 头像,作为文本,您的代码从中导出字符串值的会话对象键或格式字符串:
void AddStamps(string OrigFile, string ResultFile)
{
Document document = new Document();
using (MemoryStream ms = new MemoryStream())
{
PdfReader pdfr = new PdfReader(OrigFile);
PdfStamper pdfs = new PdfStamper(pdfr, ms);
Image image__1 = Image.GetInstance(new System.Uri("https://www.gravatar.com/avatar/6bc6e4a08a5683b6f4ef8a8eb5117114?s=48&d=identicon&r=PG"));
Image image__2 = Image.GetInstance(new System.Uri("https://www.gravatar.com/avatar/53d3aae5c986ca57f01016f5e0be82de?s=32&d=identicon&r=PG&f=1"));
Rectangle rect;
int PageCount = pdfr.NumberOfPages;
PdfContentByte content;
for (int x = 1; x <= PageCount; x++)
{
rect = pdfr.GetPageSize(x);
content = pdfs.GetOverContent(x);
image__1.SetAbsolutePosition(50.0F, 50.0F);
image__1.ScalePercent(30.0F, 30.0F);
image__2.SetAbsolutePosition(100.0F, 100.0F);
image__2.ScalePercent(30.0F, 30.0F);
content.AddImage(image__1);
content.AddImage(image__2);
PdfLayer layer = new PdfLayer("Goedkeurlaag", pdfs.Writer);
content.BeginLayer(layer);
content.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 20);
String strWatermerkText1 = "ORG_Tekeningtekst";
String strWatermerkText2 = "dd-MM-yyyy";
String strWatermerkText3 = "VolNaam";
content.SetColorFill(BaseColor.RED);
content.BeginText();
content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText3, 60, 160, 0.0F);
content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText2, 60, 185, 0.0F);
content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText1, 60, 210, 0.0F);
content.EndText();
content.EndLayer();
}
pdfs.Close();
File.WriteAllBytes(ResultFile, ms.ToArray());
}
}
运行它
将此方法应用于您的 sample file 结果如下所示:
即在每一页上都清晰可见以下标记:
因此
由于您的示例文档上的图章清晰可见,并且此处 VB 到 C# 的翻译相当忠实,因此问题是由您未提及的某些因素引起的,例如
发生一些异常(可能是在数据库访问期间或由于数据库或会话返回的某些
忽略了这些异常null
值),您使用Catch ex As Exception End Try
空捕获块。
你的图片是完全透明的,你的文字是空的。
一般
So it must be under the word text somewhere.
如果您向 pdfs.GetOverContent(x)
添加内容,它会添加到该页面的现有内容之后,并且由于 PDF 不知道 z 轴,因此以后绘制的任何内容都会覆盖之前绘制的内容。您的新内容只能被
- 稍后添加更新的内容或
- 注释内容,因为按规范的所有注释都在所有常规内容之上。
(当然也可以离屏...)
查看新示例文档
同时,OP 提供了一个不同的示例文档,并且将上面的代码应用于它确实不会产生可见的标记。
但是原因上面已经提示了:
Or, of course, it can be off-screen...
OP 的代码隐含地假定坐标系原点位于页面的左下角。虽然这种情况经常发生,但并非必须如此!
OP 的代码已经获取了页面的媒体框:
rect = pdfr.GetPageSize(x)
检查手头文件的媒体框,左下角是(0, -836.64001),右上角是(1207.68005, 0)。因此,原点位于左上角,OP 使用的所有坐标都在可见页面上方 .
如果将上面 C# 代码中的相应行替换为:
image__1.SetAbsolutePosition(rect.Left + 50.0F, rect.Bottom + 50.0F);
...
image__2.SetAbsolutePosition(rect.Left + 100.0F, rect.Bottom + 100.0F);
...
content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText3, rect.Left + 60, rect.Bottom + 160, 0.0F);
content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText2, rect.Left + 60, rect.Bottom + 185, 0.0F);
content.ShowTextAligned(PdfContentByte.ALIGN_LEFT, strWatermerkText1, rect.Left + 60, rect.Bottom + 210, 0.0F);
再次获得想要的邮票: