在 iTextSharp 中为带水印的文档加下划线
Underline a document with watermark in iTextSharp
我有一个 pdf 文档,我在其中添加了水印。结果很好,但是如果我尝试在生成的 pdf 下划线,水印是文本文档的一部分,所以下划线结果是错误的。
这里我的代码用于应用水印:
using (System.IO.MemoryStream memWatermark = new MemoryStream(pdfWatermark))
using (System.IO.MemoryStream memIn = new MemoryStream(pdfin))
using (System.IO.MemoryStream memOut = new MemoryStream())
{
memWatermark.Position = 0;
memIn.Position = 0;
memOut.Position = 0;
PdfReader reader = new PdfReader(memIn);
PdfReader wmReader = new PdfReader(memWatermark);
int j = wmReader.NumberOfPages;
if (wmReader.NumberOfPages > 0)
{
Rectangle wmSize = wmReader.GetPageSize(1);
int wmRotation = wmReader.GetPageRotation(1);
using (Document doc = new Document(wmSize))
{
PdfWriter writer = PdfWriter.GetInstance(doc, memOut);
doc.Open();
PdfImportedPage waterMarkPage = writer.GetImportedPage(wmReader, 1);
PdfImportedPage currentPage;
for (int i = 1; i <= reader.NumberOfPages; i++)
{
currentPage = writer.GetImportedPage(reader, i);
//Add the first file to coordinates 0,0
if (wmRotation == 90 || wmRotation == 270)
{
writer.DirectContent.AddTemplate(currentPage, 0, -1f, 1f, 0, 0, wmReader.GetPageSizeWithRotation(i).Height);
}
else
{
writer.DirectContent.AddTemplate(currentPage, 1f, 0, 0, 1f, 0, 0);
}
// set transparency for watermark
var gstate = new PdfGState { FillOpacity = 0.2f, StrokeOpacity = 0.4f };
writer.DirectContent.SaveState();
writer.DirectContent.SetGState(gstate);
//Since we don't call NewPage the next call will operate on the same page
if (wmRotation == 90 || wmRotation == 270)
{
writer.DirectContent.AddTemplate(waterMarkPage, 0, -1f, 1f, 0, 0, wmReader.GetPageSizeWithRotation(1).Height);
}
else
{
writer.DirectContent.AddTemplate(waterMarkPage, 1f, 0, 0, 1f, 0, 0);
}
// reset transparency state to default before adding next page
writer.DirectContent.RestoreState();
// now move to following page
if (i < reader.NumberOfPages)
{
doc.NewPage();
}
}
// flush writer but leave the stream open!
writer.Flush();
writer.CloseStream = false;
}
}
memOut.Position = 0;
if (memOut.Length > 0)
{
pdfout = new byte[memOut.Length];
pdfout = memOut.ToArray();
done = true;
}
}
我找到了这个解决方案。在图像中转换水印的 pdf 页面,然后添加该图像并将其添加到最终 pdf 的每一页。我使用 PdfiumViewer 库将 Pdf 页面转换为 PNG 图像。
这里是代码:
using (System.IO.MemoryStream memIn = new MemoryStream(pdfin))
using (System.IO.MemoryStream memOut = new MemoryStream())
{
byte[] image = null;
using (System.IO.MemoryStream memWatermark = new MemoryStream(pdfWatermark))
using (var document = PdfiumViewer.PdfDocument.Load(memWatermark))
{
using (var ms = new MemoryStream())
{
document.Render(0, 300, 300, true).Save(ms, System.Drawing.Imaging.ImageFormat.Png);
image = ms.ToArray();
}
}
PdfReader reader = new PdfReader(memIn);
int n = reader.NumberOfPages;
PdfStamper stamper = new PdfStamper(reader, memOut);
// transparency
PdfGState gs1 = new PdfGState();
gs1.StrokeOpacity = 0.4f;
gs1.FillOpacity = 0.2f;
// properties
PdfContentByte over;
iTextSharp.text.Rectangle pagesize;
float x, y;
stamper.FormFlattening = true;
stamper.FreeTextFlattening = true;
iTextSharp.text.Rectangle wmSize = reader.GetPageSize(1);
int wmRotation = reader.GetPageRotation(1);
// image watermark
var img = iTextSharp.text.Image.GetInstance(image);
float w = img.ScaledWidth;
float h = img.ScaledHeight;
using (Document doc = new Document(wmSize))
{
PdfWriter writer = PdfWriter.GetInstance(doc, memOut);
doc.Open();
PdfImportedPage currentPage;
for (int i = 1; i <= reader.NumberOfPages; i++)
{
pagesize = reader.GetPageSizeWithRotation(i);
over = writer.DirectContent;
currentPage = writer.GetImportedPage(reader, i);
if (wmRotation == 90 || wmRotation == 270)
over.AddTemplate(currentPage, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height);
else
over.AddTemplate(currentPage, 1f, 0, 0, 1f, 0, 0);
x = (pagesize.Left + pagesize.Right) / 2;
y = (pagesize.Top + pagesize.Bottom) / 2;
over.SaveState();
over.SetGState(gs1);
var pageRotation = reader.GetPageRotation(i);
if (pageRotation == 90 || pageRotation == 270)
{
if (pageRotation == 90)
{
img.RotationDegrees = 180f;
img.SetAbsolutePosition(0, 0);
over.AddImage(img);
}
else
{
img.RotationDegrees = -90f;
img.SetAbsolutePosition(-(y / 2), (x / 2));
over.AddImage(img);
}
}
else
over.AddImage(img, w, 0, 0, h, x - (w / 2), y - (h / 2));
over.RestoreState();
// now move to following page
if (i < reader.NumberOfPages)
{
doc.NewPage();
}
}
// flush writer but leave the stream open!
writer.Flush();
writer.CloseStream = false;
}
memOut.Position = 0;
if (memOut.Length > 0)
{
pdfout = new byte[memOut.Length];
pdfout = memOut.ToArray();
done = true;
}
stamper.Close();
reader.Close();
}
我有一个 pdf 文档,我在其中添加了水印。结果很好,但是如果我尝试在生成的 pdf 下划线,水印是文本文档的一部分,所以下划线结果是错误的。
这里我的代码用于应用水印:
using (System.IO.MemoryStream memWatermark = new MemoryStream(pdfWatermark))
using (System.IO.MemoryStream memIn = new MemoryStream(pdfin))
using (System.IO.MemoryStream memOut = new MemoryStream())
{
memWatermark.Position = 0;
memIn.Position = 0;
memOut.Position = 0;
PdfReader reader = new PdfReader(memIn);
PdfReader wmReader = new PdfReader(memWatermark);
int j = wmReader.NumberOfPages;
if (wmReader.NumberOfPages > 0)
{
Rectangle wmSize = wmReader.GetPageSize(1);
int wmRotation = wmReader.GetPageRotation(1);
using (Document doc = new Document(wmSize))
{
PdfWriter writer = PdfWriter.GetInstance(doc, memOut);
doc.Open();
PdfImportedPage waterMarkPage = writer.GetImportedPage(wmReader, 1);
PdfImportedPage currentPage;
for (int i = 1; i <= reader.NumberOfPages; i++)
{
currentPage = writer.GetImportedPage(reader, i);
//Add the first file to coordinates 0,0
if (wmRotation == 90 || wmRotation == 270)
{
writer.DirectContent.AddTemplate(currentPage, 0, -1f, 1f, 0, 0, wmReader.GetPageSizeWithRotation(i).Height);
}
else
{
writer.DirectContent.AddTemplate(currentPage, 1f, 0, 0, 1f, 0, 0);
}
// set transparency for watermark
var gstate = new PdfGState { FillOpacity = 0.2f, StrokeOpacity = 0.4f };
writer.DirectContent.SaveState();
writer.DirectContent.SetGState(gstate);
//Since we don't call NewPage the next call will operate on the same page
if (wmRotation == 90 || wmRotation == 270)
{
writer.DirectContent.AddTemplate(waterMarkPage, 0, -1f, 1f, 0, 0, wmReader.GetPageSizeWithRotation(1).Height);
}
else
{
writer.DirectContent.AddTemplate(waterMarkPage, 1f, 0, 0, 1f, 0, 0);
}
// reset transparency state to default before adding next page
writer.DirectContent.RestoreState();
// now move to following page
if (i < reader.NumberOfPages)
{
doc.NewPage();
}
}
// flush writer but leave the stream open!
writer.Flush();
writer.CloseStream = false;
}
}
memOut.Position = 0;
if (memOut.Length > 0)
{
pdfout = new byte[memOut.Length];
pdfout = memOut.ToArray();
done = true;
}
}
我找到了这个解决方案。在图像中转换水印的 pdf 页面,然后添加该图像并将其添加到最终 pdf 的每一页。我使用 PdfiumViewer 库将 Pdf 页面转换为 PNG 图像。
这里是代码:
using (System.IO.MemoryStream memIn = new MemoryStream(pdfin))
using (System.IO.MemoryStream memOut = new MemoryStream())
{
byte[] image = null;
using (System.IO.MemoryStream memWatermark = new MemoryStream(pdfWatermark))
using (var document = PdfiumViewer.PdfDocument.Load(memWatermark))
{
using (var ms = new MemoryStream())
{
document.Render(0, 300, 300, true).Save(ms, System.Drawing.Imaging.ImageFormat.Png);
image = ms.ToArray();
}
}
PdfReader reader = new PdfReader(memIn);
int n = reader.NumberOfPages;
PdfStamper stamper = new PdfStamper(reader, memOut);
// transparency
PdfGState gs1 = new PdfGState();
gs1.StrokeOpacity = 0.4f;
gs1.FillOpacity = 0.2f;
// properties
PdfContentByte over;
iTextSharp.text.Rectangle pagesize;
float x, y;
stamper.FormFlattening = true;
stamper.FreeTextFlattening = true;
iTextSharp.text.Rectangle wmSize = reader.GetPageSize(1);
int wmRotation = reader.GetPageRotation(1);
// image watermark
var img = iTextSharp.text.Image.GetInstance(image);
float w = img.ScaledWidth;
float h = img.ScaledHeight;
using (Document doc = new Document(wmSize))
{
PdfWriter writer = PdfWriter.GetInstance(doc, memOut);
doc.Open();
PdfImportedPage currentPage;
for (int i = 1; i <= reader.NumberOfPages; i++)
{
pagesize = reader.GetPageSizeWithRotation(i);
over = writer.DirectContent;
currentPage = writer.GetImportedPage(reader, i);
if (wmRotation == 90 || wmRotation == 270)
over.AddTemplate(currentPage, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height);
else
over.AddTemplate(currentPage, 1f, 0, 0, 1f, 0, 0);
x = (pagesize.Left + pagesize.Right) / 2;
y = (pagesize.Top + pagesize.Bottom) / 2;
over.SaveState();
over.SetGState(gs1);
var pageRotation = reader.GetPageRotation(i);
if (pageRotation == 90 || pageRotation == 270)
{
if (pageRotation == 90)
{
img.RotationDegrees = 180f;
img.SetAbsolutePosition(0, 0);
over.AddImage(img);
}
else
{
img.RotationDegrees = -90f;
img.SetAbsolutePosition(-(y / 2), (x / 2));
over.AddImage(img);
}
}
else
over.AddImage(img, w, 0, 0, h, x - (w / 2), y - (h / 2));
over.RestoreState();
// now move to following page
if (i < reader.NumberOfPages)
{
doc.NewPage();
}
}
// flush writer but leave the stream open!
writer.Flush();
writer.CloseStream = false;
}
memOut.Position = 0;
if (memOut.Length > 0)
{
pdfout = new byte[memOut.Length];
pdfout = memOut.ToArray();
done = true;
}
stamper.Close();
reader.Close();
}