как извлечь текст из pdf с помощью mupdf?

Я хочу извлечь текст из pdf и передать его. Мой код следующий:

BOOL CTextEditorDoc::loadTxt()
{
    if(m_strPDFPath.IsEmpty())
        return FALSE;

#ifdef _DEBUG
    DWORD dwTick = GetTickCount();
    CString strLog;
#endif

    CString strFile;
    fz_context *ctx;
    fz_document* doc;

    fz_matrix ctm;
    fz_page *page;
    fz_device *dev;
    fz_text_page *text;
    fz_text_sheet *sheet;
    int i,line,rotation,pagecount;

    if(!gb2312toutf8(m_strPDFPath,strFile))
        return FALSE;

    ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
    fz_try(ctx){
        doc = fz_open_document(ctx, strFile.GetBuffer(0));
    }fz_catch(ctx){
        fz_free_context(ctx);
        return FALSE;
    }

    line = 0;
    rotation = 0;
    pagecount = 0;
    pagecount = fz_count_pages(doc);

    fz_rotate(&ctm, rotation);
    fz_pre_scale(&ctm,1.0f,1.0f);

    sheet = fz_new_text_sheet(ctx);
    for(i=0;i<pagecount;i++){
        page = fz_load_page(doc,i);
        text = fz_new_text_page(ctx);
        dev = fz_new_text_device(ctx, sheet, text);

#ifdef _DEBUG
        dwTick = GetTickCount();
#endif
        fz_run_page(doc, page, dev, &ctm, NULL);

#ifdef _DEBUG
        strLog.Format("run page:%d ms\n",GetTickCount() - dwTick);
        OutputDebugString(strLog);
        dwTick = GetTickCount();
#endif

        //m_linesInfoVector.push_back(line);
        print_text_page(ctx,m_strContent,text,line);

#ifdef _DEBUG
        strLog.Format("print text:%d ms\n",GetTickCount() - dwTick);
        OutputDebugString(strLog);
        dwTick = GetTickCount();
#endif

        fz_free_device(dev);
        fz_free_text_page(ctx,text);
        fz_free_page(doc, page);
    }

    fz_free_text_sheet(ctx,sheet);
    fz_close_document(doc);
    fz_free_context(ctx);
    return TRUE;
}

Этот код может извлечь весь текст pdf, но может быть слишком медленным. Как это улучшить? Большая часть времени проводится в функции fz_run_page. Может просто для извлечения текста из pdf мне не нужно выполнять fz_run_page?


person tfzxyinhao    schedule 24.09.2013    source источник


Ответы (2)


На первый взгляд ваш код выглядит нормально.

Чтобы извлечь текст из PDF, вам необходимо интерпретировать потоки операторов PDF. fz_run_page делает это. Это приводит к обращениям к любому указанному вами устройству — в данном случае к устройству извлечения структурированного текста. Это сопоставляет случайно расположенные глифы со всей страницы в более структурированную форму слов/строк/абзацев/столбцов и т. д.

Так что, короче, вы все делаете правильно.

В настоящее время нет обслуживаемых пользователем способов улучшить скорость этого. Возможно, мы могли бы использовать подсказку устройства, чтобы избежать чтения изображений и т. Д. В будущих версиях. Я обдумаю это и обсужу с другими разработчиками. Но пока ты поступаешь правильно.

ХТН.

person Robin Watts    schedule 24.09.2013
comment
@@Robin Watts, вы считаете mupdf лучшей библиотекой PDF в мире? - person tfzxyinhao; 25.09.2013
comment
@ Робин Уоттс, что-нибудь сделано для ускорения чтения текста из pdf? - person EekTheCat; 22.07.2016

Нет, нужен вызов fz_run_page. Вам нужно интерпретировать страницы документа, чтобы вытащить текст, и это то, что делает fz_run_page.

Возможно, вы могли бы создать более простое текстовое устройство, которое не отслеживало бы позиции символов, но я сомневаюсь, что это сильно повлияет на производительность.

person Paul Gardiner    schedule 24.09.2013
comment
да, fz_new_text_device создает устройство, которое может анализировать текст только из pdf. - person tfzxyinhao; 25.09.2013