O PDF possui um espaço em branco extra em todas as palavras após executar o Ghostscript

10

Este PDF foi produzido por Abbyy Finereader 10:

http://ebooks.zeitr.org/from_abbyy.pdf

Você pode copiar e colar a primeira frase e obter este (muito bom) resultado de texto:

Der »Bund Deutscher Gymnastik-Schulleiter« quarta-feira, 20 de novembro de 1955.

Após algum processamento com o Ghostscript 9.02 (Windows de 64 bits), recebo este arquivo:

http://ebooks.zeitr.org/after_ghostscript.pdf

Agora a primeira frase parece estranha - há um espaço extra antes do último caractere de cada palavra.

Der »Bun d Deutsche r GymnastikSchulleiter« wurd eam 20. Novembe r 195 5 restaurantes anais do Zusammenkunf der der Leiterinne e leite d de privado n deutsche no GymnastikAusbildungsstätte n gegründet.

Isso tem o principal efeito negativo de que você não pode procurar palavras inteiras no Acrobat Reader. Posso reproduzir o efeito com o seguinte parâmetro mínimo definido para o Ghostscript:

-sDEVICE=pdfwrite ^
-dBATCH ^
-dNOPAUSE ^
-sstdout="myStdOut" ^
-sOutputFile="myDestFile.pdf" ^
 mySourceFile.pdf

Alguma ideia?

Kurt Pfeifle
fonte
@ Erwin Jurschitza: você gostaria de manter o link do seu arquivo from_abbyy.pdf por um tempo, para que possa ser recuperado mesmo depois de alguns meses?
Kurt Pfeifle
@ pipitas: Não tem problema, está no Amazon S3.

Respostas:

8

Achei isso um problema interessante e dei uma olhada mais de perto ...

Primeiro, usei a qpdfferramenta de linha de comando para descompactar fluxos de dados PDF, para poder ver melhor os códigos-fonte dos dois arquivos:

qpdf.exe ^
   --qdf ^
     from_abbyy.pdf ^
     qdf--from_abbyy.pdf

qpdf.exe ^
   --qdf ^
     after_ghostscript.pdf ^
     qdf--after_ghostscript.pdf

Observando uma das primeiras ocorrências em que um espaço extra é inserido (é a sequência original "Bund Deutscher Gymnastik-Schulleiter" se transformando em "Bun d Deutsche r GymnastikSchulleiter" ), encontro os seguintes trechos em PDF:

Em qdf - from_abbyy.pdf:

( Deutsche) Tj
0 Tc
(r) Tj
1 0 0 1 143.236 265.140 Tm     %% Tm = 'text matrix' operator
3.569 Tw
0.706 Tc
( Gymnastik-Schulleite) Tj

Em qdf - after_ghostscript.pdf:

( Deutsche)Tj
0 Tc
36.235 0 Td                    %% extra Td = 'move text current point' operator
(r)Tj
2.16501 0 Td                   %% Td = 'move text current point' instead of Tm
3.569 Tw
0.706 Tc
( Gymnastik-Schulleite)Tj

Para ter uma idéia do significado dos operadores gráficos PDF usados ​​aqui, veja uma pequena lista:

Tj - show text
Tc - set character spacing
Tm - set text matrix
Tw - set word spacing
Td - move text current point

Como você pode ver, o Ghostscript substituiu o operador original Tm( matriz de texto ) por um operador Td( mover ponto atual do texto ) e também adicionou um extra 2.16501 0 Td... Não sei por que isso acontece. Vou enviar um relatório de bug para o bugzilla do Ghostscript [*] e ver se eles estão interessados ​​em resolvê-lo.

Observe, no entanto, que esse problema não ocorre, se eu usar o Linux Acrobat Reader 9.4.2 e usar a ação do menu "Arquivo -> Salvar como texto ..." . Nesse caso, não há espaços adicionais (mas algumas quebras de linha extras). No Linux também, o texto não é pesquisável corretamente e também mostra os espaços extras ao copiar e colar .


[*] Vou atualizar aqui com o número do bug quando tiver feito.


Atualizar:

Depois de refletir um pouco mais sobre o Tmoperador substituído , agora acho que isso não deve ser a raiz do problema.

Ao perceber isso, tentei fazer a conversão com o Ghostscript v8.71 em vez da v9.02. E o que devo dizer? O problema de copiar e colar não ocorre com a saída v8.71!

Isso significa: existe um problema no Ghostscript 9.02 que não existia no 8.71. Provavelmente, isso tem a ver com as métricas de fonte incorporadas no PDF de saída. Como os trechos de PDF citados acima são os mesmos na saída v8.71 e na saída v9.02 ....

Atualização 2:

URL da entrada de bug no bugzilla do Ghostscript:

Atualização 3:

Esse bug parece ter sido corrigido enquanto isso. Não vejo isso acontecer com as versões do Ghostscript com as quais testei novamente: Git atual (v9.10GIT) nem com o Ghostscript v9.06.

Kurt Pfeifle
fonte
@pipitas: Muito obrigado por analisar isso!
5

Se você digitalizar uma página com texto em um PDF e executar um aplicativo OCR nele, o texto será adicionado à página, mas o "modo de renderização de texto" será definido como invisível. Está lá, mas não é renderizado na tela (ou no papel, se impresso). O que você vê ou imprime é a imagem digitalizada original.

Como podemos tornar o texto invisível visível?

Bem, podemos editar o PDF ... O código PDF para definir a renderização de texto como invisível é o seguinte:

3 Tr

Ainda não é possível encontrar essa sequência no from_abbyy.pdf original nem no from_ghostscript.pdf porque partes dos PDFs estão compactadas. Por isso, descompacte-os o máximo possível com a ajuda de qpdf:

qpdf \
 --qdf \
   from_abbyy.pdf \
   qdf--from_abbyy.pdf

qpdf \
 --qdf \
   after_ghostscript.pdf \
   qdf--after_ghostscript.pdf

Agora podemos encontrar a string acima facilmente (e há apenas uma ocorrência em cada arquivo).

Vamos mudar para um dos modos visíveis de renderização de texto. No geral, podemos escolher entre estes 8 modos de renderização de texto:

 0 -  fill glyph shapes
 1 -  stroke glyph shapes
 2 -  fill, then stroke glyph shapes
 3 -  neither fill nor stroke glyph shapes (invisible)
 4 -  fill and add to path for clipping glyph shapes
 5 -  stroke glyph shapes and add to path for clipping
 6 -  fill, then stroke glyph shapes and add path for clipping
 7 -  add glyph shapes to path for clipping

Se eu usar o modo "preenchimento", o texto do OCR provavelmente não parecerá tão bom em cima da imagem de digitalização subjacente. Portanto, eu prefiro a variante "stroke". Então eu simplesmente mudo acima da linha para ler

 1 Tr

Olhando para este PDF modificado, não gosto, porque a largura de linha padrão é muito grossa para o meu gosto. Além disso, a cor do traçado do contorno é preta (padrão); Eu prefiro o vermelho para contrastar com as formas originalmente digitalizadas. Portanto, adiciono algum código à frente desta linha que define a largura da linha para um quarto de ponto:

 .25 w

e outra para definir a cor do traçado como vermelho:

 1 0 0 RG

A linha completa agora é a seguinte:

 .25 w 1 0 0 RG 1 Tr

Isso é tudo.

Observe que nossa pouca manipulação danificou o arquivo, porque seu "sumário" (em termos técnicos: sua xreftabela) não será mais válido. No entanto, o Acrobat Reader ou o Acrobat Professional ainda o abrirão (sem se queixar) e silenciosamente "repararão" a seção xref do arquivo. Outros visualizadores de PDF podem rejeitar o arquivo, mas por enquanto não nos importamos ...

Aqui estão as capturas de tela do resultado: ampliada para a largura da janela (A primeira captura de tela é ampliada na largura da janela.) ampliada para 800% (A segunda captura de tela é ampliada em 800%.)

Os contornos vermelhos são o texto digitalizado tornado visível agora, exatamente como queríamos.

Realizei o mesmo procedimento descrito acima para os arquivos from_abbyy.pdf e after_ghostscript.pdf . Abri os dois resultados em duas instâncias diferentes do Acrobat Reader. Se fizermos os dois ampliarem para o mesmo valor e maximizarem as duas janelas, é fácil alternar a visualização entre os dois arquivos via [alt]+[tab]. Essa é uma boa maneira de revelar até as melhores diferenças de renderização entre dois arquivos PDF.

Meu resultado é: não há nem um único pixel diferente entre a entrada do Ghostscript (v9.02) e sua saída para este arquivo. Mas há uma grande diferença se você deseja copiar e colar texto ...

Kurt Pfeifle
fonte
1

Não vejo o problema descrito. Abri o arquivo PDF 'depois' com o Acrobat Professional 9.0 e o texto é copiado e colado corretamente.

O Ghostscript interpreta completamente o arquivo PDF e produz um novo arquivo PDF com base no que ele interpretou. Ele não tem relação com o arquivo original, além de registrar a posição do texto.

Devido ao rico conjunto de recursos do PDF, é possível ter caracteres posicionados no mesmo local usando vários métodos diferentes. Portanto, não há nada errado ou inesperado em si no modo como a GS está produzindo o arquivo PDF.

Como o texto pode ser salvo corretamente, é uma questão de heurísticas do Acrobat decidir se dois caracteres 'próximos' são adjacentes ou têm um espaço entre eles, quando tratados como ASCII consecutivos.

Não acredito que o problema possa ser as métricas de fonte incorporadas pelo simples motivo de que a fonte não está incorporada :-) A fonte usada é Helvetica, que não está incorporada no documento, e, portanto, Acrobat (pelo menos para mim) usa o ArialMT. Observe que o arquivo PDF 'original' também não contém as fontes.

Acabarei analisando o bug relatado, mas não será em breve e duvido que haja algo que possamos (ou faremos) sobre isso. Parece-me que isso é uma conseqüência inevitável das heurísticas. No entanto, pode ser útil incorporar as fontes, para que pelo menos elas sejam consistentes.

KenS
fonte
@ user701996: Interessante - sem problemas com o Acrobat Pro 9.0? Meu Acrobat Reader X (10.0.1, Windows) está com o problema.
@ user701996: Abri o arquivo no Acrobat Professional 9.4.4. Copiar e colar o arquivo posterior não funciona. Salvar como texto ... no entanto não funciona ....
Kurt Pfeifle
@ user701996: Mesmo que a fonte não esteja incorporada, as métricas da fonte são . Hmmm, a menos que a fonte seja uma das 'Base 14' .... Então você pode estar certo neste caso. Vou dar uma olhada mais de perto.
Kurt Pfeifle
@ user701996: Parece que você é um dos caras do Ghostscript. Você está?
Kurt Pfeifle
1

No relatório de bug do Ghostscript em:

http://bugs.ghostscript.com/show_bug.cgi?id=692206


Agora consegui reproduzir o problema, e não é uma regressão de 8.71, é uma progressão (e uma alteração da Adobe).

8.71 enviado com um bug que causou a gravação de CMOS ToUnicode inválidos. A documentação enganosa e contraditória da Adobe levou o CMap a ser escrito como um CMap, quando, de fato, o ToUnicode CMaps possui regras próprias e incompatíveis.

Normalmente, os CMaps do ToUnicode são usados ​​apenas para pesquisar e copiar / colar. Como o nome indica, eles são usados ​​para mapear códigos de caracteres para pontos de código Unicode. O ToUnicode CMap no arquivo PDF 8.71 não é usado, porque é inválido, o das versões posteriores é válido e o Acrobat é conhecido por usá-lo.

Parece que, no Acrobat Reader, até a versão 9.2, inclusive, a existência dos dados do ToUnicode não faz diferença. Em algum momento após a versão 9.2, o mecanismo de pesquisa mudou e o Acrobat parece usar dois mecanismos diferentes, dependendo da presença de um ToUnicode CMap. Não tenho acesso ao Acrobat Pro depois da versão 9.2 e apenas o Reader X instalado recentemente, não tenho nada entre eles.

O método 'no Unicode' funciona em todas as versões do Acrobat, o método 'Unicode' falha nas versões mais recentes.

Eu mostrei isso espaçando em branco a referência ao ToUnicode CMap do FontDescriptor. Se necessário, posso disponibilizar os vários arquivos, mas eles são grandes à medida que são descompactados.

Como a pesquisa é um esforço heurístico em PDF, não será possível garantir um resultado. A mudança de comportamento se deve ao Acrobat, não ao Ghostscript, e a alteração no Ghostscript foi para corrigir um bug real, portanto, uma progressão, não uma regressão.

KenS
fonte
0

Para verificar se esse problema está conectado ao 'encaixe' da fonte ou não, fiz outra conversão no Linux. Eu usei esta linha de comando para que o Ghostscript incorpore as fontes usadas:

gs \
 -o after_ghostscriptonlinux.pdf \
 -sDEVICE=pdfwrite \
 -dPDFSETTINGS=/prepress \
 -sEmbedAllFonts=true \
  from_abbyy.pdf

O Ghostscript mostrará esta saída:

GPL Ghostscript SVN PRE-RELEASE 9.02 (2011-02-07)
Copyright (C) 2010 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Processing pages 1 through 1.
Page 1
Loading NimbusSanL-Regu font from %rom%Resource/Font/NimbusSanL-Regu... 2776276 1420923 2081124 778943 3 done.
Loading NimbusSanL-ReguItal font from %rom%Resource/Font/NimbusSanL-ReguItal... 2853416 1529123 2137980 831640 3 done.
Loading NimbusSanL-Bold font from %rom%Resource/Font/NimbusSanL-Bold... 2970748 1643508 2194836 886454 3 done.

O Ghostscript incorporou fontes de uma família de fontes chamada NimbusSanL . Portanto, não há mais ArialMT , como foi usado para renderizar na tela pelo Acrobat Reader como um substituto para a Helvetica ausente (consulte também os comentários do usuário701996 acima). Observe que o Ghostscript renomeia essa fonte para Helvetica assim que for incorporada. Mas isso não é um problema, porque o NimbusSanL foi criado como um clone do Helvetica ...

No entanto, mesmo para este PDF de saída, copiar e colar do Acrobat Reader não funcionará bem. Apesar do Reader não precisar mais usar o ArialMT para substituir o Helvetica. O Reader agora usa o clone NimbusSanL / Helvetica incorporado.

Até agora, estabelecemos esses fatos sobre o texto copiado e passado do Acrobat Reader ou do Acrobat Professional:

  • A saída do Ghostscript v9.02 não funciona suficientemente bem para este arquivo.
  • Esse é o caso, se a fonte é incorporada pelo GS ou não.
  • Esse é o caso do GS no Windows XP e do GS no Linux.

  • A saída do Ghostscript v8.71 funciona bem o suficiente para este arquivo.

  • Esse é o caso, se a fonte é incorporada pelo GS ou não.
  • Esse é o caso do GS no Windows XP e do GS no Linux.

  • Mesmo para saída em que copiar e colar está quebrado, Salvar como texto ... faz.

Ainda não entendo por que esse deveria ser o caso. Mas parece claramente algum tipo de regressão (talvez menor) do Ghostscript no caminho da v8.71 para a 9.02.

Agora, vamos tentar outro software visualizador de PDF com os PDFs 'críticos':

  • Adobe Reader X dentro do Wine no Linux: copy'n'paste é b0rken da mesma maneira que na v9.4.4.
  • Evince v2.32.2 no Linux: copy'n'paste funciona.
  • O PDFXChange Viewer 2.5 (build 191) no Windows XP Prof: copy'n'paste funciona.
  • MuPDF reader 0.8 no Linux: não sei como copiar e colar - mas a 'pesquisa' funciona perfeitamente.
  • Encontrado s.th. chamado "PDF Viewer 0.1.7" no Linux: copy'n'paste funciona.
  • SumatraPDF v1.5 dentro do Wine no Linux: copy'n'paste funciona.
  • SumatraPDF v1.5.1 no Windows XP: copy'n'paste funciona.
  • FoxitReader 4.3.1.0113 no Windows XP: copiar e colar funciona.
  • Nitro PDF Reader dentro do Wine no Linux: copy'n'paste funciona.

Observe que ainda existem outras diferenças muito pequenas entre todos os leitores de PDF 'funcionais' em que meu veredicto foi copiar e colar . Como um traço ausente aqui, ou alguns espaços duplicados entre as palavras ali e outras coisas assim ... Atualmente, não tenho explicação para isso, mas provavelmente é a mesma causa raiz pela qual existe uma grande lacuna entre os produtos da Adobe (que não possui cópia e pasta de trabalho para este arquivo), uma que uma tinha e "o resto do mundo", na outra.

Kurt Pfeifle
fonte