PDF tiene un espacio en blanco adicional en todas las palabras después de ejecutar Ghostscript

10

Este PDF fue producido por Abbyy Finereader 10:

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

Puede copiar y pegar la primera oración y obtener este resultado de texto (muy bueno):

Der »Bund Deutscher Gymnastik-Schulleiter« wurde am 20. November 1955 anläßlich einer Zusammenkunft der Leiterinnen und Leiter der privaten deutschen Gymnastik-Ausbildungsstätten gegründet.

Después de un procesamiento con Ghostscript 9.02 (Windows de 64 bits) obtengo este archivo:

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

Ahora la primera oración se ve extraña: hay un espacio adicional antes del último carácter de cada palabra.

Der »Bun d Deutsche r GymnastikSchulleiter« wurd eam 20. Novembe r 195 5 anläßlic h eine r Zusammenkunf t der Leiterinne n un d Leite r de r private n deutsche n GymnastikAusbildungsstätte n gegründet.

Esto tiene el principal efecto negativo de que no puede buscar palabras completas en Acrobat Reader. Puedo reproducir el efecto con el siguiente conjunto de parámetros mínimos para Ghostscript:

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

¿Algunas ideas?

Kurt Pfeifle
fuente
@Erwin Jurschitza: ¿le importaría mantener el enlace de su archivo from_abbyy.pdf por un tiempo, para que pueda recuperarlo incluso después de unos meses?
Kurt Pfeifle
@pipitas: No hay problema, está en Amazon S3.

Respuestas:

8

Me pareció un problema interesante y lo miré más de cerca ...

Primero, utilicé la qpdfherramienta de línea de comandos para descomprimir flujos de datos PDF para poder ver mejor los códigos fuente de ambos archivos:

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

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

Al observar uno de los primeros casos en los que se inserta un espacio adicional (es la cadena original "Bund Deutscher Gymnastik-Schulleiter" que se convierte en "Bun d Deutsche r GymnastikSchulleiter" ), encuentro los siguientes fragmentos de PDF:

En 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

En 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 darle una pequeña idea de lo que significan los operadores gráficos PDF utilizados aquí, aquí hay una breve lista:

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

Como puede ver, Ghostscript reemplazó el operador original Tm( matriz de texto ) por uno Td( mover el punto actual del texto ), y también agregó un extra 2.16501 0 Td... No sé por qué es esto. Enviaré un informe de error al bugzilla de Ghostscript [*] y veré si están interesados ​​en resolverlo.

Sin embargo, tenga en cuenta que este problema no se produce si uso Linux Acrobat Reader 9.4.2 y uso la acción de menú "Archivo -> Guardar como texto ..." . En este caso, no hay espacios adicionales (pero sí algunos saltos de línea adicionales). En Linux también, el texto no se puede buscar correctamente, y también muestra los espacios adicionales al copiar y pegar ...


[*] Actualizaré aquí con el número de error cuando lo haya hecho.


Actualizar:

Después de reflexionar un poco más sobre el Tmoperador reemplazado , ahora creo que esta no debería ser la raíz del problema.

Al darme cuenta de eso, intenté hacer la conversión con Ghostscript v8.71 en lugar de v9.02. ¿Y qué debo decir? ¡El problema de copiar y pegar no ocurre con la salida v8.71!

Eso significa: hay un problema en Ghostscript 9.02 que no estaba allí en 8.71. Lo más probable es que tenga que ver con las métricas de fuente incrustadas en el PDF de salida. Debido a que los fragmentos de PDF citados anteriormente son los mismos en la salida v8.71 que en la salida v9.02 ...

Actualización 2:

URL de entrada de error en bugzilla de Ghostscript:

Actualización 3:

Este error parece haber sido corregido mientras tanto. No veo que suceda con las versiones de Ghostscript. Lo he probado nuevamente con: current Git (v9.10GIT) ni con Ghostscript v9.06.

Kurt Pfeifle
fuente
@pipitas: ¡Muchas gracias por analizar esto!
5

Si escanea una página con texto en un PDF y ejecuta una aplicación de OCR, entonces el texto se agregará a la página, pero el "modo de representación de texto" se establece en invisible. Está allí, pero no se muestra en la pantalla (o en papel si se imprime). Lo que ve o imprime es la imagen escaneada original.

¿Cómo podemos hacer visible el texto invisible?

Bueno, podemos editar el PDF ... El código PDF para configurar la representación del texto en invisible es este:

3 Tr

No puede encontrar esta cadena (todavía) en el original from_abbyy.pdf ni en from_ghostscript.pdf porque algunas partes de los archivos PDF están comprimidos. Entonces los descomprimimos lo más posible con la ayuda de qpdf:

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

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

Ahora podemos encontrar la cadena anterior fácilmente (y solo hay una aparición en cada archivo).

Cambiemos esto a uno de los modos visibles de representación de texto. En general, podemos elegir entre estos 8 modos de representación 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

Si uso el modo "relleno", el texto del OCR probablemente no se verá tan bien encima de la imagen de escaneo subyacente. Por lo tanto, prefiero la variante de "trazo". Así que simplemente cambio la línea de arriba para leer

 1 Tr

Mirando este PDF modificado, no me gusta, porque el ancho de línea predeterminado es demasiado grueso para mi gusto. Además, el color del trazo del contorno es negro (predeterminado); Prefiero el rojo para tener un contraste con las formas originalmente escaneadas. Por lo tanto, agrego un código al frente de esta línea que establece el ancho de línea en un cuarto de punto:

 .25 w

y alguna otra para establecer el color del trazo en rojo:

 1 0 0 RG

La línea completa ahora se lee:

 .25 w 1 0 0 RG 1 Tr

Eso es todo.

Tenga en cuenta que nuestra pequeña manipulación ha dañado el archivo, porque su "TOC" (en términos técnicos: su xreftabla) ya no será válida. Sin embargo, Acrobat Reader o Acrobat Professional lo abrirán (sin quejarse siquiera) y silenciosamente "repararán" la sección xref del archivo. Otros lectores de PDF pueden rechazar el archivo, pero por ahora no nos importa ...

Aquí hay capturas de pantalla del resultado: ampliado al ancho de la ventana (La primera captura de pantalla se amplía al ancho de la ventana). zoom al 800% (La segunda captura de pantalla se amplía al 800%).

Los contornos rojos son el texto escaneado que se hace visible ahora, tal como lo queríamos.

Realicé el mismo procedimiento descrito anteriormente para ambos archivos from_abbyy.pdf y after_ghostscript.pdf . Abrí ambos resultados en 2 instancias diferentes de Acrobat Reader. Si hacemos que ambos se acerquen al mismo valor y maximicemos ambas ventanas, entonces es fácil alternar la vista entre ambos archivos mediante [alt]+[tab]. Esta es una buena manera de revelar incluso las mejores diferencias de representación entre dos archivos PDF.

Mi resultado es: ni siquiera hay un solo píxel diferente entre la entrada de Ghostscript (v9.02) y su salida para este archivo. Pero hay una gran diferencia si desea copiar y pegar texto ...

Kurt Pfeifle
fuente
1

No veo el problema descrito. Abrí el archivo PDF 'después' con Acrobat Professional 9.0 y el texto se copia y pega correctamente.

Ghostscript interpreta completamente el archivo PDF y produce un nuevo archivo PDF basado en lo que interpretó, no tiene ninguna relación con el archivo original aparte de que registra la posición del texto.

Debido al rico conjunto de características de PDF, es posible tener caracteres posicionados en el mismo lugar utilizando múltiples métodos diferentes. Entonces, no hay nada malo o inesperado per se en la forma en que GS está produciendo el archivo PDF.

Dado que el texto se puede guardar correctamente, se trata de que la heurística de Acrobat decida si dos caracteres 'cercanos' son adyacentes o tienen un espacio intermedio, cuando se manejan como ASCII consecutivos.

No creo que el problema pueda ser la métrica de la fuente incrustada por la simple razón de que la fuente no está incrustada :-) La fuente que se usa es Helvetica, que no está incrustada en el documento, por lo que Acrobat (al menos para mí) usa ArialMT. Tenga en cuenta que el archivo PDF 'original' tampoco contiene las fuentes.

Eventualmente miraré el error reportado, pero no será pronto y dudo que haya algo que podamos (o hagamos) al respecto. Me parece que esta es una consecuencia inevitable de la heurística. Sin embargo, podría ser útil incrustar las fuentes, para que al menos sean consistentes.

KenS
fuente
@ user701996: Interesante: ¿no hay problemas con Acrobat Pro 9.0? Mi Acrobat Reader X (10.0.1, Windows) tiene el problema.
@ user701996: abrí el archivo en Acrobat Professional 9.4.4. Copiar y pegar el archivo posterior no funciona. Guardar como texto ... sin embargo funciona ...
Kurt Pfeifle
@ user701996: incluso si la fuente no está incrustada, las métricas de la fuente sí lo están . Hmmm, a menos que la fuente sea una de las 'Base 14' ... Entonces puede que tengas razón en este caso. Voy a echar un vistazo más de cerca.
Kurt Pfeifle
@ user701996: Parece que eres una de las personas de Ghostscript. ¿Es usted?
Kurt Pfeifle
1

Del informe de error de Ghostscript en:

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


Ahora he podido reproducir el problema, y ​​no es una regresión desde 8.71, es una progresión (y un cambio de Adobe).

8.71 se envió con un error que hizo que escribiera CMaps ToUnicode no válidos. La documentación de Adobe engañosa y contradictoria llevó a que el CMap se escribiera como un CMap, cuando de hecho ToUnicode CMaps tiene sus propias reglas incompatibles.

Los CMaps de ToUnicode normalmente solo se utilizan para buscar y copiar / pegar. Como su nombre lo indica, se utilizan para asignar códigos de caracteres a puntos de código Unicode. ToUnicode CMap en el archivo PDF 8.71 no se usa, porque no es válido, el de las versiones posteriores es válido y se sabe que Acrobat lo usa.

Parece que en Acrobat Reader hasta 9.2 inclusive, la existencia de los datos de ToUnicode no hace ninguna diferencia. En algún momento después de 9.2, el mecanismo de búsqueda cambió y Acrobat parece usar dos mecanismos diferentes dependiendo de si hay un CMU ToUnicode. No tengo acceso a Acrobat Pro después de 9.2 y solo instalé recientemente Reader X, no tengo nada en medio.

El método 'no Unicode' funciona en todas las versiones de Acrobat, el método 'Unicode' falla en las versiones más nuevas.

Mostré esto espaciando en blanco la referencia al ToUnicode CMap del FontDescriptor. Si es necesario, puedo hacer que los diversos archivos estén disponibles, pero son grandes ya que se descomprimen.

Dado que la búsqueda es un esfuerzo heurístico en PDF, no será posible garantizar un resultado. El cambio en el comportamiento se debe a Acrobat, no a Ghostscript, y el cambio en Ghostscript fue corregir un error real, por lo tanto, una progresión, no una regresión.

KenS
fuente
0

Para verificar si este problema está conectado a la 'incrustación' de la fuente o no, he realizado otra conversión, en Linux. Usé esta línea de comando para que Ghostscript incruste las fuentes utilizadas:

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

Ghostscript mostrará esta salida:

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.

Ghostscript ha incorporado fuentes de una familia de fuentes llamada NimbusSanL . Por lo tanto, no más ArialMT , como lo utilizó Acrobat Reader para representar en la pantalla como un sustituto de la Helvetica faltante (ver también los comentarios del usuario 701996 arriba). Tenga en cuenta que Ghostscript cambiará el nombre de esa fuente a Helvetica tan pronto como esté incrustado. Pero eso no es un problema, porque NimbusSanL fue creado como un clon de Helvetica ...

Sin embargo, incluso para este PDF de salida, copiar y pegar desde Acrobat Reader no funcionará bien. A pesar de que Reader ya no necesita usar ArialMT para sustituir a Helvetica. Reader ahora usa el clon NimbusSanL / Helvetica que está incrustado.

Hasta ahora, hemos establecido estos datos sobre el texto copiado y copiado de Acrobat Reader o Acrobat Professional:

  • La salida de Ghostscript v9.02 no funciona lo suficientemente bien para este archivo.
  • Ese es el caso si la fuente está incrustada por GS o si no lo está.
  • Ese es el caso de GS en Windows XP y GS en Linux.

  • La salida de Ghostscript v8.71 funciona suficientemente bien para este archivo.

  • Ese es el caso si la fuente está incrustada por GS o si no lo está.
  • Ese es el caso de GS en Windows XP y GS en Linux.

  • Incluso para la salida donde copy'n'paste está roto, Guardar como texto ... lo hace.

Todavía no entiendo por qué este debería ser el caso. Pero claramente parece una especie de regresión (quizás menor) de Ghostscript en su camino de v8.71 a 9.02.

Ahora intentemos otro software de visualización de PDF con los PDF 'críticos':

  • Adobe Reader X dentro de Wine en Linux: copy'n'paste se b0rken de la misma manera que con v9.4.4.
  • Evince v2.32.2 en Linux: copiar y pegar funciona.
  • PDFXChange Viewer 2.5 (compilación 191) en Windows XP Prof: funciona copiar y pegar.
  • MuPDF reader 0.8 en Linux: no sé cómo copiar y pegar, pero 'buscar' funciona a la perfección.
  • Encontrado s.th. llamado "PDF Viewer 0.1.7" en Linux: copy'n'paste funciona.
  • SumatraPDF v1.5 dentro de Wine en Linux: copy'n'paste funciona.
  • SumatraPDF v1.5.1 en Windows XP: copiar y pegar funciona.
  • FoxitReader 4.3.1.0113 en Windows XP: funciona copiar y pegar.
  • Nitro PDF Reader dentro de Wine en Linux: copiar y pegar funciona.

Tenga en cuenta que todavía hay otras diferencias, pero muy pequeñas, entre todos los lectores de PDF 'en funcionamiento' donde mi veredicto fue copiar y pegar . Como un guión faltante aquí, o algunos espacios duplicados entre las palabras allí, y otras cosas similares ... Actualmente no tengo ninguna explicación de por qué esto puede ser, pero probablemente sea la misma causa raíz por la cual hay una gran brecha entre los productos de Adobe (que no tiene copia y pasta en funcionamiento para este archivo) uno que no tenía y "el resto del mundo" por el otro.

Kurt Pfeifle
fuente