¿Cómo puedo convertir un archivo pdf de escala de grises a blanco y negro?


11

Mi sistema operativo es Ubuntu 12.04. ¿Cómo puedo convertir un archivo pdf de escala de grises a blanco y negro? El archivo pdf en escala de grises proviene del escaneo con la opción de escala de grises, y el OCR requiere el pdf en escala de blanco y negro.


Actualizar:

Tras la respuesta de Marco, el pdf BW no es bueno y el archivo original está aquí .


tryscantailor
frostschutz

scantailortiene un montón de otras características útiles a la hora de preparar las exploraciones para OCR, y esa es la única razón por la que me sugirió (como un comentario, no una respuesta)
frostschutz

Puede abrir y exportar (al menos algunos) .pdf en libreoffice (y, por lo tanto, supongo que la mayoría de los procesadores de texto modernos). No sé si eso hará posible o fácil el cambio deseado.
Ricitos de Oro

1
También hay pdfimages(poppler) para extraer imágenes escaneadas de su contenedor PDF. Puede ser más eficiente manejarlos con ImageMagick en primer lugar.
frostschutz

Respuestas:


9

1) Use ghostscript para convertir el PDF a un archivo PostScript monocromo usando el dispositivo psmono :

gs -q -sDEVICE=psmono -o mono.ps input.pdf

2) Luego convierta el PostScript monocromático de nuevo a PDF:

ps2pdf mono.ps

EDITAR: el psmonodispositivo crea una imagen de medio tono de 1 bit que aparentemente no es lo que desea. No pude encontrar una manera de especificar un umbral usando ghostscript, así que recurrí a imagemagick. convertinternamente usa ghostscript para convertir el PDF. Luego aplica el filtro de umbral para producir una imagen de 1 bit y usa ghostscript nuevamente para crear un PDF. Dado que convertutiliza una resolución de 75 DPI por defecto, que podría no coincidir con su resolución real, puede proporcionar el densityargumento. Y experimente con la thresholdconfiguración. Los valores óptimos dependen en gran medida del archivo de entrada.

convert -density 150 -threshold 50% input.pdf output.pdf

¡Gracias! Un problema al ejecutar el primer comando: el PDF original en escala de grises es de aproximadamente 25 MB, y la ejecución aún no ha finalizado después de 15 minutos, y el archivo de salida mono.ps ya tiene 150 MB y sigue aumentando. Me estoy preocupando por eso. ¿Hay otras formas, por ejemplo, imprimir en un archivo BW pdf?
Tim

@Tim Eso no es raro. Los archivos PostScript están sin comprimir, el PDF resultante será más pequeño.
Marco

Gracias. Tardaron unos 20 minutos. El pdf BW no es bueno. y el archivo original está aquí
Tim

@ Calidad horrible, no es adecuado para OCR, no importa lo que hagas.
frostschutz

4

La mejor manera que descubrí, sin pérdida de calidad, elimina las sombras, el ruido, el texto de la página siguiente que se filtra, etc.

1) Primero convierta pdf a imágenes individuales

pdfimages combined_ocr.pdf page

2) En segundo lugar, elimine las sombras, el ruido y el texto de la página siguiente que se filtra (créditos a este blog )

ls ./p*.ppm | xargs -L1 -I {} convert {}  -quality 100 -density 300 -fill white -fuzz 80% +opaque "#000000" {}.jpg

esto podría agregarse como un paso adicional o en lugar del comando anterior para obtener solo dos colores:

ls ./p*.ppm | xargs -L1 -I {} convert {} +dither -colors 2 -type bilevel -density 300 -fill white -fuzz 40% +opaque "#000000" -density 300 {}.jpg

3) Esto para hacer un archivo pdf de cada imagen jpg sin pérdida de resolución o calidad:

ls -1 ./*jpg | xargs -L1 -I {} img2pdf {} -o {}.pdf

4) Esto para concatenar las páginas pdf en una:

pdftk *.pdf cat output combined.pdf

5) Y por último agrego una capa de texto OCRed que no cambia la calidad del escaneo en los archivos PDF para que puedan buscarse:

pypdfocr combined.pdf 

3

También tenía algunos archivos PDF en color escaneados y archivos PDF en escala de grises que quería convertir a bw. Intenté usarlo gscon el código que aparece aquí , y la calidad de imagen es buena con el texto en PDF que todavía está allí. Sin embargo, ese código gs solo se convierte en escala de grises (como se preguntó en la pregunta) y todavía tiene un gran tamaño de archivo. convertproduce resultados muy pobres cuando se usa directamente.

Quería archivos PDF con buena calidad de imagen y tamaño de archivo pequeño. Mi solución se utiliza gspara extraer archivos bmp en escala de grises del pdf, convertpara limitar esos bmps a bw y guardarlos como archivos tiff, y luego img2pdf para comprimir las imágenes tiff y combinarlas en un solo pdf.

Intenté ir directamente a tiff desde el pdf, pero la calidad no es la misma, por lo que guardo cada página en bmp. Para un archivo pdf de una página, converthace un gran trabajo desde bmp a pdf. Ejemplo:

gs -sDEVICE=bmpgray -dNOPAUSE -dBATCH -r300x300 \
   -sOutputFile=./pdf_image.bmp ./input.pdf

convert ./pdf_image.bmp -threshold 40% -compress zip ./bw_out.pdf

Para varias páginas, gspuede combinar múltiples archivos pdf en uno, pero img2pdfproduce un tamaño de archivo más pequeño que gs. Los archivos tiff deben descomprimirse como entrada para img2pdf. Tenga en cuenta que para un gran número de páginas, los archivos intermedios bmp y tiff tienden a ser de gran tamaño. pdftko joinpdfsería mejor si pueden fusionar archivos PDF comprimidos de convert.

Me imagino que hay una solución más elegante. Sin embargo, mi método produce resultados con muy buena calidad de imagen y un tamaño de archivo mucho más pequeño. Para recuperar el texto en bw pdf, ejecute OCR nuevamente.

Mi script de shell usa gs, convert e img2pdf. Cambie los parámetros (número de páginas, ppp de escaneo,% umbral, etc.) enumerados al principio según sea necesario, y ejecútelos chmod +x ./pdf2bw.sh. Aquí está el script completo (pdf2bw.sh):

#!/bin/bash

num_pages=12
dpi_res=300
input_pdf_name=color_or_grayscale.pdf
bw_threshold=40%
output_pdf_name=out_bw.pdf
#-------------------------------------------------------------------------
gs -sDEVICE=bmpgray -dNOPAUSE -dBATCH -q -r$dpi_res \
   -sOutputFile=./%d.bmp ./$input_pdf_name
#-------------------------------------------------------------------------
for file_num in `seq 1 $num_pages`
do
  convert ./$file_num.bmp -threshold $bw_threshold \
          ./$file_num.tif
done
#-------------------------------------------------------------------------
input_files=""

for file_num in `seq 1 $num_pages`
do
  input_files+="./$file_num.tif "
done

img2pdf -o ./$output_pdf_name --dpi $dpi_res $input_files
#-------------------------------------------------------------------------
# clean up bmp and tif files used in conversion

for file_num in `seq 1 $num_pages`
do
  rm ./$file_num.bmp
  rm ./$file_num.tif
done

2

En realidad, si proviene de un escaneo, la única forma razonable es usar imágenes en pdf y convertir los gráficos subyacentes. Usé este script para convertirlo:

#!/bin/sh
if [ -z "$1" -o -z "$2" ]; then
    echo "Syntax: $0 <input.pdf> <output.pdf>"
    exit 1
fi

pdfimages "$1" scan
for a in scan*.ppm; do 
   convert -white-threshold 85% -monochrome $a `basename $a .ppm`.tiff
done
tiffcp scan*.tiff output.tiff
tiff2pdf output.tiff -o "$2" -p A4 -F
rm scan*.ppm scan*.tiff output.tiff

2

Gracias a OccamsRazor por su guión, que hace un gran trabajo al convertir PDF en color y en escala de grises en una versión monocromática legible y compacta. Este es realmente un comentario en la publicación de OccamsRazor, pero no tengo suficientes puntos para comentar.

El guión se producirá un error en el img2pdf -o ./$output_pdf_name --dpi $dpi_res $input_files que --dpiya no es un argumento aceptado para img2pdf. En cambio, obtiene la resolución del archivo de entrada, por lo que puede dejarlo fuera.

Aquí está mi versión del guión. No quería editar el script para cada archivo, por lo que paso el número de páginas y el nombre del archivo de entrada cuando lo ejecuto. Tengo el nombre de salida ajustada a y ajustar la resolución a 200 ppp, que trabaja para mi flujo de trabajo, pero puede que desee cambiar, o convertirlos en y y pasarlos en.00input_name$3$4

Para ejecutar, el uso , por ejemplo, ../pdf2bw.sh <number_of_pages> <input_name>./pdf2bw.sh 55 input.pdf

#!/bin/bash

num_pages=$1
input_pdf_name=$2
output_pdf_name="00$2"
bw_threshold=40%
dpi_res=200
#-------------------------------------------------------------------------
gs -sDEVICE=bmpgray -dNOPAUSE -dBATCH -q -r$dpi_res \
   -sOutputFile=./%d.bmp ./$input_pdf_name
#-------------------------------------------------------------------------
for file_num in `seq 1 $num_pages`
do
  convert ./$file_num.bmp -threshold $bw_threshold \
          ./$file_num.tif
done
#-------------------------------------------------------------------------
input_files=""

for file_num in `seq 1 $num_pages`
do
  input_files+="./$file_num.tif "
done

img2pdf -o ./$output_pdf_name $input_files
#-------------------------------------------------------------------------
# clean up bmp and tif files used in conversion

for file_num in `seq 1 $num_pages`
do
  rm ./$file_num.bmp
  rm ./$file_num.tif
done

Debe citar sus variables de shell; especialmente los que provienen de argumentos u otras aportaciones del usuario: por ejemplo, "./$input_pdf_name"e incluso seq 1 "$num_pages". Además, es posible que desee cambiar `…`a $(…): vea esto , esto y esto .
G-Man dice 'Reincorporar a Monica' el

Este es el script de OccamsRazor, excepto por los cambios que noté. No soy un programador de shell, así que no quería meterme con algo que funcionó. Pero si alguien quiere limpiar esto, tienes mi agradecimiento.
lowwall
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.