如何用iTextSharp为PDF添加元数据及传递图片原始宽高?
嘿,我来帮你搞定iTextSharp这两个实用需求——保留图片原始宽高到PDF,以及添加文档/每页级别的元数据。这俩都是实际项目里经常碰到的,咱们一步步拆解:
1. 保留图片原始宽高并写入PDF
iTextSharp默认可能会根据文档页面尺寸自动缩放图片,或者压缩时丢失原始尺寸信息。要解决这个,咱们得先获取图片的原始像素尺寸和DPI,再转换成PDF的标准单位(点,1英寸=72点),然后强制设置图片的显示尺寸为原始比例对应的大小。另外,如果需要后续读取PDF时能直接拿到原始像素宽高,还要把这些值存到自定义元数据里。
代码示例:添加图片并保留原始尺寸
string imagePath = "your-image-file.jpg"; Document document = new Document(); PdfWriter writer = PdfWriter.GetInstance(document, new FileStream("output.pdf", FileMode.Create)); document.Open(); using (var imageStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read)) { Image img = Image.GetInstance(imageStream); // 获取图片原始像素宽高 int originalWidthPx = img.Width; int originalHeightPx = img.Height; // 获取图片的DPI(如果图片没有嵌入DPI信息,默认用96,这是常见屏幕DPI) float dpiX = img.DpiX > 0 ? img.DpiX : 96; float dpiY = img.DpiY > 0 ? img.DpiY : 96; // 转换为PDF的点单位(1英寸=72点) float widthInPoints = originalWidthPx / dpiX * 72; float heightInPoints = originalHeightPx / dpiY * 72; // 强制设置图片的显示尺寸为原始比例,避免自动缩放 img.ScaleAbsolute(widthInPoints, heightInPoints); // 把图片添加到文档 document.Add(img); } document.Close();
2. 添加元数据(文档级+每页独立数据)
元数据分两种:文档全局的(比如标题、关键词),和每页独立的(比如当前页图片的原始宽高),咱们分别处理:
2.1 文档级元数据
iTextSharp的Document对象自带方法设置标准元数据,也可以通过PdfWriter.Info添加自定义键值对。
代码示例:设置文档元数据
Document document = new Document(); PdfWriter writer = PdfWriter.GetInstance(document, new FileStream("output.pdf", FileMode.Create)); // 设置标准元数据 document.AddTitle("图片原始尺寸保留示例"); document.AddKeywords("iTextSharp, PDF, 图片尺寸, 元数据"); document.AddAuthor("Kaija"); document.AddSubject("演示如何在PDF中存储图片原始信息"); // 添加自定义文档级元数据(比如全局的图片信息) writer.Info.Add("GlobalImageCount", "2"); document.Open(); // ... 添加内容 ... document.Close();
2.2 每页独立数据
要给每页存独立的信息(比如当前页图片的原始宽高),需要利用iTextSharp的页面事件(PdfPageEventHelper),在每页结束时把自定义数据写入页面字典。
步骤1:自定义页面事件类
public class CustomPageMetadataEvent : PdfPageEventHelper { // 用来临时存储当前页的图片原始宽高 public int CurrentImageWidthPx { get; set; } public int CurrentImageHeightPx { get; set; } public override void OnEndPage(PdfWriter writer, Document document) { // 获取当前页的PDF字典对象 PdfDictionary pageDictionary = writer.PageDict; // 添加自定义键值对到页面字典,键名用PdfName避免编码问题 pageDictionary.Put(new PdfName("OriginalImageWidthPx"), new PdfNumber(CurrentImageWidthPx)); pageDictionary.Put(new PdfName("OriginalImageHeightPx"), new PdfNumber(CurrentImageHeightPx)); } }
步骤2:使用自定义事件添加每页数据
Document document = new Document(); PdfWriter writer = PdfWriter.GetInstance(document, new FileStream("multi-page.pdf", FileMode.Create)); // 实例化自定义事件并绑定到Writer CustomPageMetadataEvent pageEvent = new CustomPageMetadataEvent(); writer.PageEvent = pageEvent; document.Open(); // 第一页:添加图片并设置当前页元数据 string firstImagePath = "page1-image.jpg"; using (var stream = new FileStream(firstImagePath, FileMode.Open)) { Image img = Image.GetInstance(stream); int widthPx = img.Width; int heightPx = img.Height; // 把当前图片的原始宽高赋值给事件对象 pageEvent.CurrentImageWidthPx = widthPx; pageEvent.CurrentImageHeightPx = heightPx; // 转换尺寸并添加到文档 float dpiX = img.DpiX > 0 ? img.DpiX : 96; float dpiY = img.DpiY > 0 ? img.DpiY : 96; img.ScaleAbsolute(widthPx / dpiX * 72, heightPx / dpiY * 72); document.Add(img); } // 新建第二页 document.NewPage(); // 第二页:添加另一张图片并设置元数据 string secondImagePath = "page2-image.jpg"; using (var stream = new FileStream(secondImagePath, FileMode.Open)) { Image img = Image.GetInstance(stream); int widthPx = img.Width; int heightPx = img.Height; pageEvent.CurrentImageWidthPx = widthPx; pageEvent.CurrentImageHeightPx = heightPx; float dpiX = img.DpiX > 0 ? img.DpiX : 96; float dpiY = img.DpiY > 0 ? img.DpiY : 96; img.ScaleAbsolute(widthPx / dpiX * 72, heightPx / dpiY * 72); document.Add(img); } document.Close();
后续读取PDF中的元数据
如果要读取这些数据,可以用PdfReader:
using (PdfReader reader = new PdfReader("multi-page.pdf")) { // 读取文档级元数据 Console.WriteLine("文档标题:" + reader.Info["Title"]); Console.WriteLine("自定义全局数据:" + reader.Info["GlobalImageCount"]); // 读取每页的自定义数据 for (int i = 1; i <= reader.NumberOfPages; i++) { PdfDictionary pageDict = reader.GetPageN(i); PdfNumber width = (PdfNumber)pageDict.Get(new PdfName("OriginalImageWidthPx")); PdfNumber height = (PdfNumber)pageDict.Get(new PdfName("OriginalImageHeightPx")); Console.WriteLine($"第{i}页图片原始宽高:{width.IntValue}px × {height.IntValue}px"); } }
内容的提问来源于stack exchange,提问作者Kaija
相关产品推荐
相关产品推荐

