簡體   English   中英

通過iTextSharp 4.1.6.0從Pdf中提取圖像

[英]Extract Images from Pdf via iTextSharp 4.1.6.0

大家好(您也是Bruno :))。
我正在使用為Xamarin .Android移植的iTextSharp 4.1.6.0。
由於某些原因,我需要從pdf中提取圖像。
創辦了太多的例子,但似乎他們不是我的情況可以接受的,因為一些類(如:
ImageCodeInfo,ImageRenderInfo,System.Drawing.Imaging.EncoderParameters,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(this System.Linq.ParallelQuery,int)'的類型參數。 嘗試顯式指定類型參數

我不知道如何解決。 能給我解釋一下嗎?

另外,我想知道是否存在另一種從pdf提取圖像的方法。
謝謝!!

首先 ,關於從舊的,過時的和不再受官方支持的軟件升級的強制性演講:

請升級到iTextSharp的最新版本。 我知道您會說您不能使用iText的新許可證,但是請閱讀其銷售常見問題解答 ,特別是針對4.1.6的“我為什么不應該使用...”部分。 請記住,在大多數國家/地區,接受許可證實際上會使您簽訂法律合同,因此我也將邀請具有法律經驗的人來閱讀。 因為您說過您正在使用Xamarin,所以我也想將其提交給商店,因此這尤為重要,因為問題會迅速蔓延。

另外,很快就會有一個新版本的PDF出現,您可能也希望能夠支持它。

其次 ,您的代碼做出了一個巨大而錯誤的假設,即PDF中的所有圖像都是JPEG。 請參閱這篇文章這篇文章中有關它的一些討論。 也許您的PDF都是JPEG,所以這對您有用,但是很有可能會破壞“明天”。

第三 ,我無法讓ElementAtICollection一起使用。 我不知道如果我錯過了一個擴展或者using的地方,但它似乎是從一個五歲后復制的代碼, 這里是來自一個六歲的崗位在這里 我也不確定為什么為什么仍然需要“第一個”元素,這很奇怪。 解決方案是僅遍歷鍵,而不是嘗試顯式地獲取鍵。 代替:

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);
}

這個小小的變化將使我們所有人哭泣,但它應該至少使圖像提取工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM