2013-12-11 14 views
5

Bir PDF dosyasından iTextSharp kütüphanesini kullanarak bir dizeye okumaya çalışıyorum.PDF dosyasından okuma metni .NET içinde

iTextSharp.text.pdf.PdfReader pdfReader = new iTextSharp.text.pdf.PdfReader(@"C:\mypdf.pdf"); 
ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy(); 
string currentText = PdfTextExtractor.GetTextFromPage(pdfReader, 1, strategy); 
text = Encoding.UTF8.GetString(ASCIIEncoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(currentText))); 
pdfReader.Close(); 
Console.WriteLine(text); 

Bu normalde Tamam çalışır, ancak her birkaç satır boşluk gibi çıkışı ile beni bırakarak, ihmal edilecek: "thisismyoutputwithoutwhitespace". Doğru şekilde ayrıştırılan metin, yazılmayan metinle aynı gibi görünüyor; Aynı metin tutarlı bir şekilde ayrıştırılmayacak, bu da bana PDF'lerde bir şey olduğunu düşündürüyor.

cevap

6

PDF dosyasının içerik akışında "sözcükler" fikri yok. Dolayısıyla, iText (Sharp) 'ın metin çıkarma uygulamasında, karakterlerin nasıl kelimelerle gruplandırılacağını belirleyen bazı sezgisel yöntemler vardır. 2 karakter arasındaki mesafe, geçerli fonttaki bir alanın yarısından daha büyük olduğunda, boşluk boşluk eklenir.

Büyük olasılıkla, boşluk olmadan ayıklanan metnin "boşluk/2" den küçük sözcükler arasında uzaklıklar vardır. SimpleTextExtractionStrategy.RenderText() yılında

:

if (spacing > renderInfo.GetSingleSpaceWidth()/2f){ 
    AppendTextChunk(' '); 
} 

Sen SimpleTextExtractionStrategy genişletmek ve RenderText() ayarlayabilirsiniz.

LocationTextExtractionStrategy içinde daha uygundur. Yalnızca IsChunkAtWordBoundary() geçersiz kılmak gerekir:

protected bool IsChunkAtWordBoundary(TextChunk chunk, TextChunk previousChunk) { 
    float dist = chunk.DistanceFromEndOf(previousChunk); 
    if(dist < -chunk.CharSpaceWidth || dist > chunk.CharSpaceWidth/2.0f) 
     return true; 

    return false; 
} 

Sen PDF'leri için iyi sonuçlar elde etmek için biraz deneme gerekecek. Durumunuzda "boşluk genişliği/2" görünüşte çok büyük. Ama eğer onu çok küçük olacak şekilde ayarlarsanız, yanlış pozitifler elde edersiniz: kelimeler içinde boşluklar eklenir.

+0

Çok teşekkür ederim! Bu çok yardımcı. Ancak, IsChunkAtBounary() 'nin geçersiz kılınabileceğinden emin misiniz? "Geçersiz kılma, çünkü soyut, sanal olarak işaretlenmez" alıyorum. Yeni bir sınıf oluşturdum, LocationTextExtractionStrategy genişletilmiş ve yöntemi geçersiz kıldım. –

+0

Bu, Java'dan C# 'a bir taşıma hatası gibi görünüyor. Bunun bir sonraki sürümde sabitlendiğinden emin olacağım. Bir geçici çözüm olarak, ITextExtractionStrategy arabiriminin tamamen yeni bir uygulamasını etkin bir şekilde yaratarak, LocationTextExtractionStrategy kodunu kopyalamanız gerektiğini düşünüyorum. Yeni uygulamanızda isChunkAtWordBoundary yöntemini ayarlayabilirsiniz. Biliyorum ... en temiz çözüm değil. C# ile aşina değilim; belki daha fazla C# deneyime sahip biri daha zarif bir çözüm düşünebilir. – rhens

+0

Eğer LocationTextExtractionStrategy'in kaynak koduna sahip değilseniz, burada bulabilirsiniz (en güncel sürüm): http://sourceforge.net/p/itextsharp/code/HEAD/tree/trunk/src/core/iTextSharp /text/pdf/parser/LocationTextExtractionStrategy.cs – rhens

İlgili konular