通过iTextSharp 4.1.6.0从Pdf中提取图像

时间:2015-11-12 15:46:06

标签: c# image xamarin itextsharp extract

大家好(你也布鲁诺 :))  我使用移植到 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中提取图像的方法 谢谢!

1 个答案:

答案 0 :(得分:2)

首先,关于从旧的,过时的,不再正式支持的软件升级的强制性演讲:

请升级到最新版本的iTextSharp。我知道你会说你不能使用iText的新许可证,但请阅读他们的sales FAQ,特别是&#34;为什么我不能使用...&#34; 4.1.6节。请记住,在大多数国家/地区,接受许可证实际上会将您纳入法律合同中,因此我也会让具有法律经验的人员阅读该合同。既然你说你正在使用Xamarin我也认为你将它提交到商店,所以这更重要,因为这些问题可以快速增加。

此外,很快就会推出新版本的PDF,您可能也希望能够支持这一版本。

第二,您的代码会产生一个巨大而错误的假设,即PDF中的所有图像都是JPEG。有关它的一些讨论,请参阅this postthis 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);
}

这个微小的变化会让我们大家都哭,但它应该使图像的提取起作用。