You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:23:58