1. 程式人生 > 實用技巧 >開發筆記:PDF生成文字和圖片水印

開發筆記:PDF生成文字和圖片水印

背景

團隊手裡在做的一個專案,其中一個小功能是使用者需要上傳PDF檔案到檔案伺服器上,都是一些合同或者技術評估文件,鑑於知識版權和防偽的目的,需要在上傳的PDF檔案打上水印,

這時候我們需要提供能力給客戶,讓他們可以對自己上傳的文件,配置文字或者圖片水印。

實現

於是我們參考了網上的一些資料,首選Spire.Pdf 和 iTextSharp,資料很多,是專業的PDF操作元件。

Spire.Pdf

SpireNuget安裝

直接安裝最新的版本就可以了

Spire程式碼段

這是生成圖片水印,註釋很清晰了。

 1  #region Spire.Pdf 元件
 2             
 3             //
建立PdfDocument物件 4 PdfDocument pdf = new PdfDocument(); 5 //載入現有PDF文件 6 pdf.LoadFromFile(@"E:\WaterMark\ATAM.pdf"); 7 //載入圖片到System.Drawing.Image物件 8 System.Drawing.Image image = System.Drawing.Image.FromFile(@"E:\WaterMark\logo.png"); 9 //
遍歷文件每一頁(可以指定只是輪詢某一個頁面) 10 foreach (PdfPageBase page in pdf.Pages) 11 { 12 //設定背景圖 13 page.BackgroundImage = image; 14 //設定背景圖的位置及大小(這邊根據我們實際的圖片大小進行同比縮小) 15 page.BackgroundRegion = new RectangleF((page.ActualSize.Width - 500
) / 2, 16 (page.ActualSize.Height - 500)/2, 500, 250); 17 //設定背景透明度 18 page.BackgroudOpacity = 0.5f; 19 } 20 //儲存並關閉文件(不關閉貌似開啟的時候會有異常) 21 pdf.SaveToFile(@"E:\WaterMark\ATAM_WaterMark.pdf"); 22 pdf.Close(); 23 24 #endregion

Spire實現結果

看著還行,起碼達到效果了

Spire擴充套件:文字水印

 1 //載入PDF文件
 2 PdfDocument pdf = new PdfDocument();
 3 pdf.LoadFromFile(@"E:\WaterMark\ATAM.pdf");
 4 
 5 //獲取PDF文件的第一頁
 6 PdfPageBase page = pdf.Pages[0];
 7 
 8 //繪製文字,設定文字格式並將其新增到頁面
 9 PdfTilingBrush brush = new PdfTilingBrush(new SizeF(page.Canvas.ClientSize.Width / 2, page.Canvas.ClientSize.Height / 3));
10 brush.Graphics.SetTransparency(0.3f);
11 brush.Graphics.Save();
12 brush.Graphics.TranslateTransform(brush.Size.Width / 2, brush.Size.Height / 2);
13 brush.Graphics.RotateTransform(-45);
14 PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("Arial Unicode MS", 20f), true);
15 brush.Graphics.DrawString("這邊定製你的文字水印", font, PdfBrushes.Red, 0, 0, new PdfStringFormat(PdfTextAlignment.Center));
16 brush.Graphics.Restore();
17 brush.Graphics.SetTransparency(1);
18 page.Canvas.DrawRectangle(brush, new RectangleF(new PointF(0, 0), page.Canvas.ClientSize));
19 
20 //儲存文件
21 pdf.SaveToFile(@"E:\WaterMark\ATAM_WaterMark.pdf");
22 pdf.Close();

iTextSharp

iTextSharpNuget安裝

一樣,直接安裝最新版本即可

iTextSharp程式碼段

這是iTextSharp生成圖片水印的方法程式碼,註釋一樣很清晰。

 1         /// <summary>
 2         /// 打水印功能
 3         /// </summary>
 4         /// <param name="infilepath">輸入檔案地址</param>
 5         /// <param name="outfilepath">輸出檔案地址</param>
 6         /// <param name="picName">圖片檔案地址</param>
 7         /// <param name="picHeight">圖片高度(可選)</param>
 8         /// <param name="picWidth">圖片寬度(可選)</param>
 9         /// <param name="top">圖片在PDF中的位置Top(可選)</param>
10         /// <param name="left">圖片在PDF中的位置Left(可選)</param>
11         /// <returns></returns>
12         public bool PDFWatermark(string infilepath, string outfilepath, string picName,float picHeight=0,float picWidth=0,float top = 0,float left=0)
13         {
14             PdfReader pdfReader = null;
15             PdfStamper pdfStamper = null;
16             try
17             {
18                 pdfReader = new PdfReader(infilepath);
19                 int numberOfPages = pdfReader.NumberOfPages;
20                 iTextSharp.text.Rectangle psize = pdfReader.GetPageSize(1);
21                 float width = psize.Width;
22                 float height = psize.Height;
23                 pdfStamper = new PdfStamper(pdfReader, new FileStream(outfilepath, FileMode.Create));
24                 PdfContentByte waterMarkContent;
25                 iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(picName);
26                 if (picHeight != 0) image.ScaleAbsoluteHeight(picHeight);
27                 else picHeight = image.Height;
28                 if (picWidth != 0) image.ScaleAbsoluteWidth(picWidth);
29                 else picWidth = image.Width;
30                 image.GrayFill = 20; // 透明度,灰色填充
31                                      // image.Rotation // 旋轉
32                                      // image.RotationDegrees // 旋轉角度
33                 // 水印的位置 
34                 if (left == 0) left = (width - picWidth) / 2;
35                 if (top == 0) top = (height - picHeight) / 2;
36                 image.SetAbsolutePosition(left,top);
37                 // 每一頁加水印,也可以設定某一頁加水印 
38                 for (int i = 1; i <= numberOfPages; i++)
39                 {
40                     waterMarkContent = pdfStamper.GetUnderContent(i);//水印在最底層
41                     //這邊注意,如果想要水印在最頂層,這邊改成 pdfStamper.GetOverContent
42                     waterMarkContent.AddImage(image);
43                 }
44                 return true;
45             }
46             catch (Exception ex)
47             {
48                 ex.Message.Trim();
49                 return false;
50             }
51             finally
52             {
53 
54                 if (pdfStamper != null) pdfStamper.Close();
55                 if (pdfReader != null) pdfReader.Close();
56             }
57         }

應用

1   #region iTextSharp            
2             string source = @"E:\WaterMark\ATAM.pdf"; //模板路徑
3             string output = @"E:\WaterMark\ATAM_WaterMark.pdf"; //匯出水印背景後的PDF
4             string watermark = @"E:\WaterMark\logo.png";   // 水印圖片
5             bool isSurrcess = PDFWatermark(source, output, watermark,250,500,0,0);            
6  #endregion

iTextSharp實現結果

也不錯,這個貌似實現起來更加靈活。

iTextSharp擴充套件:文字水印

 1    /// <summary>
 2         /// 新增文字水印
 3         /// </summary>
 4         /// <param name="filePath">pdf檔案地址</param>
 5         /// <param name="text">水印文字</param>
 6         public static void SetWatermark(string filePath, string text)
 7         {
 8             PdfReader pdfReader = null;
 9             PdfStamper pdfStamper = null;
10             string tempPath = Path.GetDirectoryName(filePath) + Path.GetFileNameWithoutExtension(filePath) + "_temp.pdf";
11             try
12             {
13                 pdfReader = new PdfReader(filePath);
14                 pdfStamper = new PdfStamper(pdfReader, new FileStream(tempPath, FileMode.Create));
15                 int total = pdfReader.NumberOfPages + 1;
16                 iTextSharp.text.Rectangle psize = pdfReader.GetPageSize(1);
17                 float width = psize.Width;
18                 float height = psize.Height;
19                 PdfContentByte content;
20                 BaseFont font = BaseFont.CreateFont(@"C:\WINDOWS\Fonts\SIMFANG.TTF", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
21                 PdfGState gs = new PdfGState();
22                 for (int i = 1; i < total; i++)
23                 {
24                     //在內容上方加水印(下方加水印參考上面圖片程式碼做法)
25                     content = pdfStamper.GetOverContent(i);
26                    //透明度
27                     gs.FillOpacity = 0.3f;
28                     content.SetGState(gs);
29                     //寫入文字
30                     content.BeginText();
31                     content.SetColorFill(BaseColor.GRAY);
32                     content.SetFontAndSize(font, 30);
33                     content.SetTextMatrix(0, 0);
34                     content.ShowTextAligned(Element.ALIGN_CENTER, text, width - 120, height - 120, -45);
35                     content.EndText();
36                 }
37             }
38             catch (Exception ex)
39             {
40                 throw ex;
41             }
42             finally
43             {
44                 if (pdfStamper != null)pdfStamper.Close();
45                 if (pdfReader != null)pdfReader.Close();
46                 File.Copy(tempPath, filePath, true);
47                 File.Delete(tempPath);//刪除臨時檔案
48             }
49         }

參考資料

Spire.Pdf:https://www.cnblogs.com/Yesi/p/4913603.html

iTextSharp:https://www.cnblogs.com/xishuqingchun/p/3838185.html

後記

程式碼都是片段,沒有進一步優化封裝,主要是為了驗證可行性。兩個元件都好用,可以去官網看看文件,有很多功能提供使用。