Extrair texto de todas as páginas de um PDF usando C++
Extrair Texto de Todas as Páginas de um Documento PDF
Extrair texto de um documento PDF é uma exigência comum. No exemplo a seguir, você verá como o Aspose.PDF para C++ permite extrair texto de todas as páginas de um documento PDF. Você precisa criar um objeto da classe TextAbsorber. Depois disso, abra o PDF usando a classe Document e chame o método ‘Accept’ da coleção Pages. A classe TextAbsorber absorve o texto do documento e retorna na propriedade ‘Text’. O trecho de código a seguir mostra como extrair texto de todas as páginas de um documento PDF.
using namespace System;
using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Text;
void ExtractTextFromAllThePages() {
std::clog << __func__ << ": Start" << std::endl;
// String para nome do caminho
String _dataDir("C:\\Samples\\Parsing\\");
// String para nome do arquivo
String infilename("sample-4pages.pdf");
String outfilename("extracted-text.txt");
// Abrir documento
auto document = MakeObject<Document>(_dataDir + infilename);
// Criar objeto TextAbsorber para extrair texto
auto textAbsorber = MakeObject<TextAbsorber>();
// Aceitar o absorvedor para todas as páginas
document->get_Pages()->Accept(textAbsorber);
// Obter o texto extraído
auto extractedText = textAbsorber->get_Text();
System::IO::File::WriteAllText(_dataDir + outfilename, extractedText);
std::clog << __func__ << ": Finish" << std::endl;
}
Chame o método Accept em uma página específica do objeto Document. O Índice é o número da página específica de onde o texto precisa ser extraído.
void ExtractTextFromParticularPage() {
std::clog << __func__ << ": Start" << std::endl;
// String para nome do caminho
String _dataDir("C:\\Samples\\Parsing\\");
// String para nome do arquivo
String infilename("sample-4pages.pdf");
String outfilename("extracted-text.txt");
// Abrir documento
auto document = MakeObject<Document>(_dataDir + infilename);
// Criar objeto TextAbsorber para extrair texto
auto textAbsorber = MakeObject<TextAbsorber>();
// Aceitar o absorvedor para todas as páginas
document->get_Pages()->idx_get(1)->Accept(textAbsorber);
// Obter o texto extraído
auto extractedText = textAbsorber->get_Text();
System::IO::File::WriteAllText(_dataDir + outfilename, extractedText);
std::clog << __func__ << ": Finish" << std::endl;
}
Extrair Texto das Páginas usando Dispositivo de Texto
Você pode usar a classe TextDevice para extrair texto de um arquivo PDF. TextDevice usa TextAbsorber em sua implementação, assim, de fato, eles fazem a mesma coisa, mas TextDevice foi implementado apenas para unificar a abordagem “Device” para extrair qualquer coisa da página, como ImageDevice, PageDevice, etc. TextAbsorber pode extrair texto de Página, PDF inteiro ou XForm, este TextAbsorber é mais universal
Extrair texto de todas as páginas
Os passos a seguir e o trecho de código mostram como extrair texto de um PDF usando o dispositivo de texto.
- Crie um objeto da classe Document com o arquivo PDF de entrada especificado
- Crie um objeto da classe TextDevice
- Use um objeto da classe TextExtractOptions para especificar as opções de extração
- Use o método Process da classe TextDevice para converter os conteúdos em texto
- Salve o texto no arquivo de saída
void ExtractTextUsingTextDevice() {
std::clog << __func__ << ": Start" << std::endl;
// String para o nome do caminho
String _dataDir("C:\\Samples\\Parsing\\");
// String para o nome do arquivo
String infilename("sample-4pages.pdf");
String outfilename("extracted-text.txt");
// Abrir documento
auto document = MakeObject<Document>(_dataDir + infilename);
auto builder = MakeObject<System::Text::StringBuilder>();
// String para armazenar o texto extraído
String extractedText;
for (auto page : document->get_Pages()) {
auto textStream = MakeObject<System::IO::MemoryStream>();
// Criar dispositivo de texto
auto textDevice = MakeObject<Aspose::Pdf::Devices::TextDevice>();
// Definir opções de extração de texto - definir modo de extração de texto (Bruto ou Puro)
auto textExtOptions = MakeObject<TextExtractionOptions>(TextExtractionOptions::TextFormattingMode::Pure);
textDevice->set_ExtractionOptions(textExtOptions);
// Converter uma página específica e salvar texto no stream
textDevice->Process(page, textStream);
// Fechar stream de memória
textStream->Close();
// Obter texto do stream de memória
extractedText = System::Text::Encoding::get_Unicode()->GetString(textStream->ToArray());
builder->Append(extractedText);
}
// Salvar o texto extraído no arquivo de texto
System::IO::File::WriteAllText(_dataDir + outfilename, builder->ToString());
std::clog << __func__ << ": Finish" << std::endl;
}
Extrair Texto de uma região específica da página
A classe TextAbsorber fornece a capacidade de extrair texto de uma página específica ou de todas as páginas de um documento PDF. Esta classe retorna o texto extraído na propriedade ‘Text’. No entanto, se tivermos a necessidade de extrair texto de uma região específica da página, podemos usar a propriedade Rectangle de TextSearchOptions. A propriedade Rectangle aceita um objeto Rectangle como valor e, usando esta propriedade, podemos especificar a região da página da qual precisamos extrair o texto.
O método Accept de uma página é chamado para extrair o texto. Crie objetos das classes Document e TextAbsorber. Chame o método ‘Accept’ na página individual, como Page Index, do objeto Document. O Index é o número da página específica de onde o texto precisa ser extraído. Você pode obter texto da propriedade ‘Text’ da classe TextAbsorber. O trecho de código a seguir mostra como extrair texto de uma página individual.
void ExtractTextFromParticularPageRegion() {
std::clog << __func__ << ": Start" << std::endl;
// String para nome do caminho
String _dataDir("C:\\Samples\\Parsing\\");
// String para nome do arquivo
String infilename("sample-4pages.pdf");
String outfilename("extracted-text.txt");
// Abrir documento
auto document = MakeObject<Document>(_dataDir + infilename);
// Criar objeto TextAbsorber para extrair texto
auto textAbsorber = MakeObject<TextAbsorber>();
textAbsorber->get_TextSearchOptions()->set_LimitToPageBounds(true);
textAbsorber->get_TextSearchOptions()->set_Rectangle(MakeObject<Rectangle>(100, 200, 250, 350));
// Aceitar o absorvedor para todas as páginas
document->get_Pages()->idx_get(1)->Accept(textAbsorber);
// Obter o texto extraído
auto extractedText = textAbsorber->get_Text();
System::IO::File::WriteAllText(_dataDir + outfilename, extractedText);
std::clog << __func__ << ": Finish" << std::endl;
}
Extrair texto com base em colunas
PDF é um formato muito popular, e por boas razões: com PDF, você pode ter praticamente certeza de que seu documento será exibido e impresso da mesma forma em diferentes computadores.
No entanto, documentos PDF sofrem com a desvantagem de que geralmente não possuem informações sobre o que é conteúdo em parágrafos, tabelas, figuras, informações de cabeçalho/rodapé, e assim por diante.
Aspose.PDf para C++ - é uma ferramenta fácil de usar, que permite extrair texto com base em colunas.
void ExtractTextBasedOnColumns() {
std::clog << __func__ << ": Start" << std::endl;
// String para nome do caminho
String _dataDir("C:\\Samples\\Parsing\\");
// String para nome do arquivo
String infilename("sample-4pages.pdf");
String outfilename("extracted-text.txt");
// Abrir documento
auto document = MakeObject<Document>(_dataDir + infilename);
// Criar objeto TextAbsorber para extrair texto
auto textFragmentAbsorber = MakeObject<TextFragmentAbsorber>();
// Aceitar o absorvedor para todas as páginas
document->get_Pages()->Accept(textFragmentAbsorber);
auto tfc = textFragmentAbsorber->get_TextFragments();
for (auto tf : tfc)
{
// Precisa reduzir o tamanho da fonte pelo menos 70%
auto size = tf->get_TextState()->get_FontSize() * 0.7f;
tf->get_TextState()->set_FontSize(size);
}
auto stream = MakeObject<System::IO::MemoryStream>();
document->Save(stream);
document = MakeObject<Document>(stream);
auto textAbsorber = MakeObject<TextAbsorber>();
document->get_Pages()->Accept(textAbsorber);
String extractedText = textAbsorber->get_Text();
System::IO::File::WriteAllText(_dataDir + outfilename, extractedText);
std::clog << __func__ << ": Finish" << std::endl;
}
Segunda abordagem - Usando ScaleFactor
Nesta nova versão, também introduzimos várias melhorias no TextAbsorber e no mecanismo interno de formatação de texto. Agora, durante a extração de texto usando o modo ‘Puro’, você pode especificar a opção ScaleFactor e essa pode ser outra abordagem para extrair texto de um documento PDF com múltiplas colunas além da abordagem mencionada acima. Este fator de escala pode ser configurado para ajustar a grade que é utilizada para o mecanismo interno de formatação de texto durante a extração de texto. Especificar os valores de ScaleFactor entre 1 e 0.1 (inclusive 0.1) tem o mesmo efeito que a redução da fonte.
Especificar os valores de ScaleFactor entre 0.1 e -0.1 é tratado como valor zero, mas faz com que o algoritmo calcule automaticamente o fator de escala necessário durante a extração de texto. O cálculo é baseado na largura média dos glifos da fonte mais popular na página, mas não podemos garantir que no texto extraído nenhuma string da coluna alcance o início da próxima coluna. Observe que se o valor de ScaleFactor não for especificado, o valor padrão de 1.0 será usado. Isso significa que não haverá escalonamento. Se o valor de ScaleFactor especificado for mais que 10 ou menos que -0.1, o valor padrão de 1.0 será usado.
Sugerimos o uso de escalonamento automático (ScaleFactor = 0) ao processar um grande número de arquivos PDF para extração de conteúdo de texto. Ou definir manualmente a redução redundante da largura da grade (cerca de ScaleFactor = 0.5). No entanto, você não deve determinar se o escalonamento é necessário para documentos concretos ou não. Se você definir a redução redundante da largura da grade para o documento (que não precisa disso), o conteúdo de texto extraído permanecerá totalmente adequado. Por favor, dê uma olhada no seguinte trecho de código.
void ExtractTextUsingScaleFactor() {
std::clog << __func__ << ": Start" << std::endl;
// String para o nome do caminho
String _dataDir("C:\\Samples\\Parsing\\");
// String para o nome do arquivo
String infilename("sample-4pages.pdf");
String outfilename("extracted-text.txt");
// Abrir documento
auto document = MakeObject<Document>(_dataDir + infilename);
auto textAbsorber = MakeObject<TextAbsorber>();
textAbsorber->set_ExtractionOptions(MakeObject<TextExtractionOptions>(TextExtractionOptions::TextFormattingMode::Pure));
// Definir fator de escala para 0.5 é suficiente para dividir colunas na maioria dos documentos
// A definição de zero permite ao algoritmo escolher o fator de escala automaticamente
textAbsorber->get_ExtractionOptions()->set_ScaleFactor(0.5); /* 0; */
document->get_Pages()->Accept(textAbsorber);
String extractedText = textAbsorber->get_Text();
System::IO::File::WriteAllText(_dataDir + outfilename, extractedText);
std::clog << __func__ << ": Finish" << std::endl;
}
Extrair Texto Destacado de Documento PDF
Em vários cenários de extração de texto de um documento PDF, você pode ter a necessidade de extrair apenas o texto destacado do documento PDF. Para implementar essa funcionalidade, adicionamos os métodos TextMarkupAnnotation.GetMarkedText() e TextMarkupAnnotation.GetMarkedTextFragments() na API. Você pode extrair o texto destacado do documento PDF filtrando TextMarkupAnnotation e usando os métodos mencionados. O trecho de código a seguir mostra como você pode extrair o texto destacado de um documento PDF.
void ExtractHighlightedText() {
std::clog << __func__ << ": Start" << std::endl;
// String para nome do caminho
String _dataDir("C:\\Samples\\Parsing\\");
// String para nome do arquivo
String infilename("sample-highlight.pdf");
String outfilename("extracted-text.txt");
// Abrir documento
auto document = MakeObject<Document>(_dataDir + infilename);
// Loop através de todas as anotações
for (auto annotation : document->get_Pages()->idx_get(1)->get_Annotations())
{
// Filtrar TextMarkupAnnotation
if (annotation->get_AnnotationType() == Aspose::Pdf::Annotations::AnnotationType::Highlight)
{
auto highlightedAnnotation = System::DynamicCast<Aspose::Pdf::Annotations::HighlightAnnotation>(annotation);
// Recuperar fragmentos de texto destacados
auto collection = highlightedAnnotation->GetMarkedTextFragments();
for (auto tf : collection)
{
// Exibir texto destacado
String s = tf->get_Text();
std::cout << s << std::endl;
}
}
}
}
Acessar Elementos de Fragmento de Texto e Segmento a partir de XML
Às vezes, precisamos acessar itens TextFragment ou TextSegment ao processar documentos PDF gerados a partir de XML. Aspose.PDF para C++ fornece acesso a esses itens por nome. O trecho de código abaixo mostra como usar essa funcionalidade.
void AccessTextFragmentandSegmentElementsXML()
{
std::clog << __func__ << ": Start" << std::endl;
// String para o nome do caminho
String _dataDir("C:\\Samples\\Parsing\\");
// String para o nome do arquivo
String infilename("sample-doc.xml");
String outfilename("sample-doc.pdf");
auto document = MakeObject<Document>();
document->BindXml(_dataDir + infilename);
System::SharedPtr<Page> page = System::DynamicCast<Aspose::Pdf::Page>(document->GetObjectById(u"mainSection"));
// Faça algumas operações com a página
// ...
System::SharedPtr<TextSegment> segment = System::DynamicCast<Aspose::Pdf::Text::TextSegment>(document->GetObjectById(u"product_description"));
// Faça algumas operações com o segmento
// ...
document->Save(_dataDir + outfilename);
std::clog << __func__ << ": Finish" << std::endl;
}