使用iTextSharp为PDF添加图片水印后文件损坏问题排查
解决iTextSharp添加图片水印后PDF损坏的问题
你的代码调试无异常但最终PDF损坏,核心原因是**PdfStamper未完成完整写入操作**,同时存在资源释放不彻底、文件操作风险高等问题,以下是修复方案:
修复后的完整代码
string sourceFilePath = Server.MapPath(@"~/uploadfiles/PDFFileName.pdf"); string tempImagePath = Server.MapPath("~/uploadfiles/Image.png"); string tempPdfPath = Server.MapPath(@"~/uploadfiles/Temp_PDFFileName.pdf"); // 生成水印图片(用PNG保留透明通道,水印效果更自然) using (Bitmap bitmap = new Bitmap(200, 30, System.Drawing.Imaging.PixelFormat.Format32bppArgb)) using (Graphics graphics = Graphics.FromImage(bitmap)) { graphics.Clear(Color.Transparent); using (var font = new System.Drawing.Font("Arial", 12, FontStyle.Bold)) using (var brush = new SolidBrush(Color.FromArgb(128, 255, 0, 0))) // 半透明红色,优化水印观感 { graphics.DrawString(text, font, brush, new PointF(0.4F, 2.4F)); } bitmap.Save(tempImagePath, ImageFormat.Png); } byte[] outputBytes; // 直接读取原文件,同时确保所有PDF操作对象正确释放 using (var reader = new PdfReader(sourceFilePath)) using (var stream = new MemoryStream()) using (var stamper = new PdfStamper(reader, stream)) { var img = iTextSharp.text.Image.GetInstance(tempImagePath); img.SetAbsolutePosition(200, 400); int pages = reader.NumberOfPages; for (int i = 1; i <= pages; i++) { var waterMark = stamper.GetUnderContent(i); waterMark.AddImage(img); } // 关键:显式关闭stamper,确保所有PDF内容写入内存流 stamper.Close(); outputBytes = stream.ToArray(); } // 清理临时文件并替换原PDF(先写临时文件再替换,避免原文件损坏) File.Delete(tempImagePath); File.WriteAllBytes(tempPdfPath, outputBytes); File.Delete(sourceFilePath); File.Move(tempPdfPath, sourceFilePath);
关键修复说明
- 强制完成PDF写入:必须调用
stamper.Close(),这是修复PDF损坏的核心操作——未关闭时,内存流中只保存了部分PDF数据,导致文件不完整。 - 优化资源管理:所有实现
IDisposable的对象(Bitmap、Graphics、Font、PdfReader等)都用using块包裹,避免资源泄漏和潜在的文件占用问题。 - 降低文件操作风险:先写入临时PDF再替换原文件,避免处理失败导致原文件丢失。
- 优化水印效果:改用PNG格式保存水印图片,支持透明通道,避免白色背景破坏PDF内容观感。
内容的提问来源于stack exchange,提问作者MuhammadElshater
相关产品推荐
相关产品推荐

