大家好(你也布鲁诺 :))
我使用移植到 Xamarin .Android的iTextSharp 4.1.6.0。
出于某种原因,我需要从pdf中提取图像
我创建了太多的例子,但似乎我的案例是不可接受的,因为有些类(例如:
ImageCodeInfo , ImageRenderInfo , System.Drawing.Imaging.EncoderParameters < / strong>, PdfImageObject 等等,并不存在)。
但是一个例子看起来不错,就是这样:
void ExtractJpeg(string file)
{
var dir1 = Path.GetDirectoryName(file);
var fn = Path.GetFileNameWithoutExtension(file);
var dir2 = Path.Combine(dir1, fn);
if (!Directory.Exists(dir2)) Directory.CreateDirectory(dir2);
var pdf = new PdfReader(file);
int n = pdf.NumberOfPages;
for (int i = 1; i <= n; i++)
{
var pg = pdf.GetPageN(i);
var res = PdfReader.GetPdfObject(pg.Get(PdfName.RESOURCES)) as PdfDictionary;
var xobj = PdfReader.GetPdfObject(res.Get(PdfName.XOBJECT)) as PdfDictionary;
if (xobj == null) continue;
var keys = xobj.Keys;
if (keys.Count == 0) continue;
var obj = xobj.Get(keys.ElementAt(0));
if (!obj.IsIndirect()) continue;
var tg = PdfReader.GetPdfObject(obj) as PdfDictionary;
var type = PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE)) as PdfName;
if (!PdfName.IMAGE.Equals(type)) continue;
int XrefIndex = (obj as PRIndirectReference).Number;
var pdfStream = pdf.GetPdfObject(XrefIndex) as PRStream;
var data = PdfReader.GetStreamBytesRaw(pdfStream);
var jpeg = Path.Combine(dir2, string.Format("{0:0000}.jpg", i));
File.WriteAllBytes(jpeg, data);
}
}
这一行的问题:
var obj = xobj.Get(keys.ElementAt(0));
错误日志:
方法的类型参数 `System.Linq.ParallelEnumerable.ElementAt(此 System.Linq.ParallelQuery,int)&#39;无法从中推断出来 用法。尝试明确指定类型参数
我不知道如何制定解决方法。有人可以解释一下吗?
另外,我想知道是否存在另一种从pdf中提取图像的方法 谢谢!
答案 0 :(得分:2)
首先,关于从旧的,过时的,不再正式支持的软件升级的强制性演讲:
请升级到最新版本的iTextSharp。我知道你会说你不能使用iText的新许可证,但请阅读他们的sales FAQ,特别是&#34;为什么我不能使用...&#34; 4.1.6节。请记住,在大多数国家/地区,接受许可证实际上会将您纳入法律合同中,因此我也会让具有法律经验的人员阅读该合同。既然你说你正在使用Xamarin我也认为你将它提交到商店,所以这更重要,因为这些问题可以快速增加。
此外,很快就会推出新版本的PDF,您可能也希望能够支持这一版本。
第二,您的代码会产生一个巨大而错误的假设,即PDF中的所有图像都是JPEG。有关它的一些讨论,请参阅this post和this post。也许你的PDF都是JPEG格式,所以这对你有用,但这很有可能会破坏&#34;明天&#34;。
第三次,我无法ElementAt
使用ICollection
。我不知道我是否错过了某个扩展程序或using
某个地方,但似乎您复制了来自六岁的一个五岁的帖子here中的代码发表here。我也不确定为什么&#34;首先&#34;无论如何都需要元素,这很奇怪。解决方案是只是循环键,而不是试图只是明确地抓住一个。而不是:
var obj = xobj.Get(keys.ElementAt(0));
//...
File.WriteAllBytes(jpeg, data);
遍历每个键:
foreach (PdfName k in keys) {
var obj = xobj.Get(k);
//...
File.WriteAllBytes(jpeg, data);
}
这个微小的变化会让我们大家都哭,但它应该使图像的提取起作用。