2008-10-13 8 views
2

J'essaie d'implémenter la mise en évidence des résultats de recherche pour les fichiers PDF dans une application Web. J'ai les pdfs d'origine, et les petites versions de png qui sont utilisées dans les résultats de recherche. Essentiellement, je suis à la recherche d'un api comme:Comment obtenir des informations de décalage de caractères à partir d'un document PDF?

pdf_document.find_offsets('somestring') 
# => { top: 501, left: 100, bottom: 520, right: 150 }, { ... another box ... }, ... 

Je sais qu'il est possible d'obtenir cette information d'un pdf parce que Preview.app d'Apple implémente cette.

besoin de quelque chose qui fonctionne sur Linux et est idéalement open source. Je suis conscient que vous pouvez le faire avec Acrobat sur Windows.

+0

Salut quackingduck, Avez-vous été en mesure de trouver une réponse à cette question? Si oui, veuillez l'afficher ici. – Thushan

Répondre

1

Je pense que vous pouvez le faire en utilisant le logiciel Adobe Acrobat SDK, une version Linux qui peut être downloaded for free from Adobe. Vous pouvez l'utiliser pour extract text from PDFs, puis calculer les offsets. Le PDF peut ensuite être mis en évidence en utilisant le Acrobat XML highlighting file. Il est utilisé pour spécifier les mots dans lesquels les positions doivent être mis en évidence et est amené à acrobate comme suit:

http://example.com/a.pdf#xml=http://example.com/highlightfile.xml

4

CAM::PDF peut faire la partie de la géométrie tout à fait bien, mais il a des problèmes avec la chaîne correspondant parfois. La technique serait quelque chose comme le code suivant légèrement testé:

use CAM::PDF; 
my $pdf = CAM::PDF->new('my.pdf') or die $CAM::PDF::errstr; 
for my $pagenum (1 .. $pdf->numPages) { 
    my $pagetree = $pdf->getPageContentTree($pagenum) or die; 
    my @text = $pagetree->traverse('MyRenderer')->getTextBlocks; 
    for my $textblock (@text) { 
     print "text '$textblock->{str}' at ", 
      "($textblock->{left},$textblock->{bottom})\n"; 
    } 
} 

package MyRenderer; 
use base 'CAM::PDF::GS'; 

sub new { 
    my ($pkg, @args) = @_; 
    my $self = $pkg->SUPER::new(@args); 
    $self->{refs}->{text} = []; 
    return $self; 
} 
sub getTextBlocks { 
    my ($self) = @_; 
    return @{$self->{refs}->{text}}; 
} 
sub renderText { 
    my ($self, $string, $width) = @_; 
    my ($x, $y) = $self->textToDevice(0,0); 
    push @{$self->{refs}->{text}}, { 
     str => $string, 
     left => $x, 
     bottom => $y, 
     right => $x + $width, 
     #top => $y + ???,                     
    }; 
    return; 
} 

où la sortie ressemble à ceci:

text 'E' at (52.08,704.16) 
text 'm' at (73.62096,704.16) 
text 'p' at (113.58936,704.16) 
text 'lo' at (140.49648,704.16) 
text 'y' at (181.19904,704.16) 
text 'e' at (204.43584,704.16) 
text 'e' at (230.93808,704.16) 
text ' N' at (257.44032,704.16) 
text 'a' at (294.6504,704.16) 
text 'm' at (320.772,704.16) 
text 'e' at (360.7416,704.16) 
text 'Employee Name' at (56.4,124.56) 
text 'Employee Title' at (56.4,114.24) 
text 'Company Name' at (56.4,103.92) 

Comme vous pouvez le voir à partir de cette sortie, la mise en correspondance de chaîne sera un peu fastidieux, mais la géométrie est simple (sauf peut-être pour la hauteur de police).

Questions connexes