使用iTextSharp批量转图片为PDF时遇流读取错误求助
问题分析与解决方案
先说说这个错误是什么意思
System.NotSupportedException: 'Stream does not support reading.'说白了就是:你传给iTextSharp.text.Image.GetInstance()的那个流没法读——要么是创建流的时候没给读取权限,要么是流已经被关了/状态不对,还有一种可能是流根本没正确初始化(比如文件路径错了,流没打开成功)。
你的代码里踩了几个坑
我仔细看了你的代码,发现几个直接导致这个错误的问题:
1. 用错了SafeFileNames,拿不到正确的文件路径
OpenFileDialog.SafeFileNames返回的只是文件名(比如test.jpg),不是完整的文件路径(比如C:\Users\Austin\Pictures\test.jpg)。如果选的图片不在你程序运行的文件夹里,new FileStream(file, ...)根本找不到文件,流初始化失败,自然就会报“不支持读取”的错。
2. PDF文档的打开/关闭逻辑完全错了
你在foreach循环里每次都执行PdfWriter.GetInstance(doc, stream)、doc.Open()和doc.Close():
PdfWriter.GetInstance只需要调用一次,它是用来把文档和输出的PDF流绑定的;doc.Open()要放在循环前,doc.Close()要放在循环后——每次循环就关文档,会直接把输出的PDF流搞废掉,后面再用这个流的时候状态就乱了,间接影响到图片流的读取。
3. 额外提醒:图片直接加可能超出页面(可选修复)
这个不是导致错误的原因,但直接加图片大概率会超出PDF的A4页面,最好调整一下大小适配页面。
修复后的完整代码
下面是改好的代码,把所有问题都解决了:
namespace WindowsFormsApp2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private OpenFileDialog ofd = new OpenFileDialog { Multiselect = true, Filter = "Image files | *.jpg;*.jpeg;*.png;" // 这里去掉了*和.jpg之间的空格,不然过滤规则会失效 }; // Open file button private void button1_Click(object sender, EventArgs e) { // 只有选中文件才执行后续逻辑 if (ofd.ShowDialog() == DialogResult.OK) { // 创建默认A4大小的PDF文档 Document doc = new Document(); using (var pdfStream = new FileStream("test.pdf", FileMode.Create, FileAccess.Write, FileShare.None)) { // 只需要绑定一次文档和输出流 PdfWriter.GetInstance(doc, pdfStream); // 循环前打开文档 doc.Open(); // 改用FileNames获取完整文件路径 foreach (string filePath in ofd.FileNames) { using (var imageStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { var image = iTextSharp.text.Image.GetInstance(imageStream); // 调整图片大小适配PDF页面(推荐加上) // 计算缩放比例,确保图片不超出页面宽高 float scale = Math.Min(doc.PageSize.Width / image.Width, doc.PageSize.Height / image.Height); image.ScaleAbsolute(image.Width * scale, image.Height * scale); // 让图片居中显示 image.Alignment = iTextSharp.text.Image.ALIGN_CENTER; doc.Add(image); // 每张图片单独一页的话就加这行,不需要就删掉 doc.NewPage(); } } // 所有图片处理完再关闭文档 doc.Close(); } } } } }
补充说明
- 我把
Filter里的空格去掉了(原来的* .jpg改成*.jpg),不然你的文件过滤会失效,看不到图片文件; - 加了图片缩放和居中的逻辑,避免图片超出PDF页面;
- 如果不需要每张图片单独占一页,把
doc.NewPage()删掉就行。
内容的提问来源于stack exchange,提问作者Austin
相关产品推荐
相关产品推荐

