3

ハイパーリンクが(同じPDFドキュメント内で)移動するPDFドキュメント内のポイントでテキスト抽出を開始できるある種の(無料の)SDKを知っている人はいますか?リンクは、特定のページの特定のポイントに移動することになります。

より具体的には、テストに対する質問と回答(および各質問/回答の関連するメモ)を保持するPDFドキュメントを解析し、必要な関連部分のみをテキストファイルにエクスポートできるプログラムが必要です。

基本的に、PDFドキュメントには、ドキュメントの先頭に向かってテスト用の質問があり、各質問内には、PDFドキュメントの別の部分にある回答と関連するメモへのハイパーリンクがあります。

PS-次の言語のいずれかを使用:C ++、Java、VB.net、C#.net、javascriptPPS-フリーソフトウェアのみ

4

3 に答える 3

1

これは思ったより難しく、質問を再考する必要があるかもしれません。ドキュメント内のハイパーリンクは通常、リンク先が「Goto View」アクションに設定されたリンク注釈によって行われます。そのビューには、必ずしも境界やポイントが含まれているとは限りません。ページ (現在のズーム) またはページ (幅に合わせる) またはページ (上部、特定のズーム) の場合もあります。さらに複雑なのは、リンク先が順番に実行されるアクションのツリーであり、各アクションが 18 の異なる可能なアクション タイプの 1 つである場合があるためです。これには、視聴者を特定のリンク先に移動させるために使用できる JavaScript が含まれます。

「リンクの先」にも苦労すると思います。

Atalasoft dotAnnotate と PDF テキスト抽出アドオンを使用して、C# でこのタスクの多くを実行できます (免責事項、私は Atalasoft で働いており、PDF-> 注釈インポーターを作成し、Acrobat v 1、2、& で Adob​​e で働いていました)。 3)。いいえ、申し訳ありませんが、これはフリー ソフトウェアではありません。

これが私がそれを行う方法です(免責事項-これは私の頭のすぐ上にあります):

class PageAnnots : KeyValuePair<int, List<PdfLinkData>> { }

public PageAnnots GetPageLinkDestinations(Stream stm)
{
    PdfAnnotationDataImporter importer = new PdfAnnotationDataImporter(stm);
    List<PageAnnots> pageAnnots = new List<PageAnnots>();

    try {
        importer.Load();
        // this gets all annotations on all pages.  On long docs, this will be time consuming
        AnnotationDataCollection allAnnots = importer.Import();
        int pageNo = 0;
        // allAnnots is a collection of LayerData, each LayerData object being a collection
        // of annots for a page.  The collection is empty if there are no annots
        foreach (AnnotationData pageOfAnnots in allAnnots) {
            List<PdfLinkData> linkAnnots = new List<PdfLinkData>();
            LayerData pageLayer = pageOfAnnots as LayerData;
            if (pageLayer != null) {
                // filter out each annot that is a link
                foreach (AnnotationData annot in pageLayer.Items) {
                    PdfLinkData link = annot as PdfLinkData;
                    if (link != null)
                        linkAnnots.Add(link);
                }
            }
            if (linkAnnots.Count > 0) {
                pageAnnots.Add(new PageAnnots(pageNo, linkAnnots));
            }
            pageNo++;
        }
    }
    catch (Exception err) {
        // keep it?  drop it?
    }

    return pageAnnots;
}

この時点で、これをキーと値のペアのコレクションに減らしました。各キーはページ番号であり、各値はそのページのリンクを表す PdfLinkData オブジェクトの空でないリストです。

そこから、このコレクションを反復処理して、次のように目的地を見つけようとすることができます。

private int PageFromDestination(PdfDestination dest)
{
    PdfIndexedPageReference pageRef = dest.Page as PdfIndexedPageReference;
    return pageRef == null ? -1 : pageRef.PageIndex;
}

public void FigureDestination(PdfLinkData link)
{
    PdfActionList actions = link.ClickAction;
    foreach (PdfAction action in actions) {
        PdfGoToViewAction gotoView = action as PdfGoToViewAction;
        if (action == null)
            continue;
        // this only pulls the page from the destination.  The dest
        // may also contain information about the view.  I'm assuming you
        // only want the page number
        int page = PageFromDestination(gotoView.Destination);
        if (page >= 0) {
            // here's where you step in - the click action could be
            // a long chain of things including several GoToView actions.
            // it's up to you to decide what you want to do.  Handle only
            // action lists of length 1?  Stop at first GoToView?
            // aggregate them all?
        }
    }
}

そして、このコードを見ると、索引付けされたページ参照とアクション・タイプおよびアクション・リストに関して、一体なぜこのレベルの抽象化があるのか​​疑問に思うでしょう。答えは、GoToView アクションは別のドキュメントを参照することもできるということです。ドキュメント間のリンクは PDF で有効です。dotAnnotate は現在それらをサポートしていませんが、将来的にはサポートできるようになる予定です。同様に、アクションは、埋め込まれた PDF ドキュメントのビューに移動することを示すことができます (はい、PDF を PDF に埋め込むことができます)。

dotAnnotate はかなり高レベルのオブジェクトの限られたセットを提供し、PDF 仕様を知って理解する必要がないことに注意する必要があります (あまり)。過去に、非常に粒度の細かい API を TIFF のようなものにリリースしようとしましたが、お客様がそれらを気に入らないことがわかりました。そのため、お客様が何を求め、必要とする可能性が高いかを推測し、消化しやすい API を作成しようとしました。

iText と iTextSharp を使用すると、API を非常に細かいレベルで制御できますが、必要なものを取得するには PDF 仕様を理解する必要があります。

たとえば、注釈の抽出を行うには、ドキュメントを開き、ページ カタログを取得し、ページ ツリーを調べて、Annots キーを持つすべてのページ辞書を見つけ、Annots 配列を調べて、そこにある各辞書でキーを検索する必要があります。値 /Annot を持つ /Type および値 /Link を持つキー /SubType の場合、存在する場合はキー /Dest の値を引き出し、それが null でない場合はそれを使用し、それ以外の場合はキー /A を見て、アクション ツリーを使用して、キー /Type が /GoTo (IIRC) に設定されたアクションを見つけ、そこから移動します。

宛先は、直接の宛先の場合もあれば、名前付きの宛先の場合もあります。名前付き宛先の場合は、文書カタログに戻って名前ツリーを取り出し、名前付き宛先で名前を検索し、見つかったらそこにある情報を引き出す必要があります。

そうです、iText や別の同様の PDF パーサーを使用できますが、ライブラリの作成者の 1 人が親切に対応してくれなければ、これらの手順をすべて実行する必要があります。

于 2010-10-26T20:25:48.167 に答える
1

箱から出してすぐに必要なことだけを実行できる有料または無料のソフトウェアを私は知りません。使用するライブラリに関係なく、おそらくいくつかのコードを作成する必要があります。結局のところ、PDF 内のテキストは任意の順序である可能性があるため、少なくともテキスト座標を計算して、不要なテキストを適切に除外する必要があります。また、リンクの注釈は PDF 内にある必要があり、そのリンク先に関する情報を取得する必要があります。

Docotic.Pdf ライブラリ (免責事項: 私は Bit Miracle で働いています) は、注釈とテキスト座標の両方で役立ちます。「リンク ターゲットからテキストを抽出する」サンプルがあり、タスクに似た方法を示しています。サンプルへのリンクを投稿するのは、それがあなた (フリーでないソフトウェアを使用することに決めた場合) や他の人にとって役立つことを願ってです。

于 2010-11-02T15:29:51.890 に答える
0

iText(Java&C#)はそれを行うことができますが、「すぐに使える」わけではありません。たとえば、どこから探し始めるかを決定するには、低レベルのPDFオブジェクト操作(およびいくつかの計算)を行う必要があります。

良いニュースは、特定のバウンディングボックスからのみテキストを抽出するテキスト抽出「戦略」があることです。コードは次のようになります。

http://www.itextpdf.com/examples/iia.php?id=279

リンクから目的地を取得することは、便利な例が浮かんでいるようなものではありません。PDF仕様を確認する必要があります(adobeには無料のコピーがあります...他のいくつかのPDFタグ付きの質問で言及されていますが、このマシンにはリンクがありません)。

于 2010-10-22T05:39:01.540 に答える