Como posso converter um arquivo pdf de escala de cinza para preto e branco?


11

Meu sistema operacional é o Ubuntu 12.04. Como posso converter um arquivo pdf de escala de cinza para preto e branco? O arquivo pdf em escala de cinza vem da digitalização com a opção em escala de cinza, e o pdf em escala em preto e branco é exigido pelo OCR.


Atualizar:

Na sequência da resposta de Marco, o BW pdf não é bom e o arquivo original é aqui .


tentescantailor
frostschutz

scantailortem toneladas de outras características úteis quando se trata de preparar scans para OCR, e essa é a única razão pela qual eu sugeri-lo (como um comentário, não uma resposta)
frostschutz

Você pode abrir e exportar (pelo menos alguns) .pdf no libreoffice (e, portanto, eu acho que a maioria dos processadores de texto modernos). Não sei se isso tornará possível ou fácil a alteração desejada.
Goldilocks

1
Há também pdfimages(poppler) para extrair imagens digitalizadas do seu contêiner PDF. Pode ser mais eficiente lidar com eles com o ImageMagick em primeiro lugar.
frostschutz 28/07

Respostas:


9

1) Use o ghostscript para converter o PDF em um arquivo PostScript monocromático usando o dispositivo psmono :

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

2) Em seguida, converta o PostScript monocromático novamente em PDF:

ps2pdf mono.ps

EDIT: O psmonodispositivo cria uma imagem de meio-tom de 1 bit que aparentemente não é o que você deseja. Não consegui encontrar uma maneira de especificar um limite usando o ghostscript, então recorri ao imagemagick. convertusa internamente o ghostscript para converter o PDF. Em seguida, aplica a filtragem de limite para produzir uma imagem de 1 bit e usa o ghostscript novamente para criar um PDF. Como convertusa uma resolução de 75DPI por padrão, que pode não corresponder à sua resolução real, você pode fornecer o densityargumento. E experimente com a thresholdconfiguração. Os valores ideais dependem muito do arquivo de entrada.

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

Obrigado! Um problema ao executar o primeiro comando: o pdf original em escala de cinza tem cerca de 25 MB e a execução ainda não foi concluída após 15 minutos, e o arquivo de saída mono.ps já tem 150 MB e continua aumentando. Estou preocupado com isso. Existem outras maneiras, por exemplo, de imprimir em arquivo PDF BW?
Tim

@ Tim Isso não é incomum. Os arquivos PostScript não são compactados, o PDF resultante será menor.
Marco

Obrigado. Demorou cerca de 20 minutos. O pdf BW não é bom. e o arquivo original está aqui
Tim

Qualidade horrível @ Tim, não adequada para OCR, não importa o que você faça.
28713 frostschutz

4

A melhor maneira que eu descobri por aí, sem perda de qualidade, remove sombras, ruído, texto da página seguinte sangrando etc:

1) Primeiro converta pdf para imagens individuais

pdfimages combined_ocr.pdf page

2) Segundo, remova sombras, ruído e texto da próxima página (créditos para este blog )

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

isso pode ser adicionado como uma etapa extra ou em vez do comando acima para obter apenas duas cores:

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

3) Para criar um arquivo pdf de cada imagem jpg sem perda de resolução ou qualidade:

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

4) Para concatenar as páginas pdf em uma:

pdftk *.pdf cat output combined.pdf

5) E, por último, adiciono uma camada de texto com OCR que não altera a qualidade da digitalização nos PDFs para que possam ser pesquisados:

pypdfocr combined.pdf 

3

Eu também tinha alguns PDFs em cores digitalizados e em escala de cinza que queria converter para bw. Tentei usar gscom o código listado aqui e a qualidade da imagem é boa com o texto em pdf ainda lá. No entanto, esse código gs é convertido apenas em escala de cinza (conforme solicitado na pergunta) e ainda possui um tamanho de arquivo grande. convertproduz resultados muito ruins quando usado diretamente.

Eu queria PDFs BW com boa qualidade de imagem e tamanho pequeno de arquivo. Minha solução usa gspara extrair arquivos bmp em escala de cinza do pdf, convertpara limitar esses bmps a bw e salvá-los como arquivos tiff e, em seguida, img2pdf para compactar as imagens tiff e mesclá-las em um único pdf.

Eu tentei ir diretamente para tiff do pdf, mas a qualidade não é a mesma, então eu salvei cada página em bmp. Para um arquivo pdf de uma página, convertfaz um ótimo trabalho de bmp para pdf. Exemplo:

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

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

Para várias páginas, é gspossível mesclar vários arquivos pdf em um, mas img2pdfgera um tamanho de arquivo menor que o gs. Os arquivos tiff devem ser descompactados como entrada para img2pdf. Lembre-se de que, para um grande número de páginas, os arquivos intermediários bmp e tiff tendem a ser grandes. pdftkou joinpdfseria melhor se eles pudessem mesclar arquivos PDF compactados convert.

Imagino que exista uma solução mais elegante. No entanto, meu método produz resultados com qualidade de imagem muito boa e tamanho de arquivo muito menor. Para recuperar o texto no PDF bw, execute o OCR novamente.

Meu script de shell usa gs, convert e img2pdf. Altere os parâmetros (número de páginas, dpi de digitalização,% de limite etc.) listados no início, conforme necessário, e execute chmod +x ./pdf2bw.sh. Aqui está o 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

Na verdade, se vier de uma digitalização, a única maneira razoável é usar pdfimages e converter os gráficos subjacentes. Eu usei esse script para convertê-lo:

#!/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

Agradecemos a OccamsRazor por seu script, que faz um ótimo trabalho de conversão de PDFs em cores e em escala de cinza em uma versão monocromática compacta e legível. Este é realmente um comentário no post de OccamsRazor, mas não tenho pontos suficientes para comentar.

O script falhará, img2pdf -o ./$output_pdf_name --dpi $dpi_res $input_files pois --dpinão é mais um argumento aceito para img2pdf. Em vez disso, obtém a resolução do arquivo de entrada, para que você possa deixá-la de fora.

Aqui está a minha versão do script. Como não queria editar o script para cada arquivo, passo o número de páginas e o nome do arquivo quando o executo. Eu tenho o conjunto nome de saída para e conjunto de resolução de 200 dpi, o que funciona para o meu trabalho, mas você pode querer mudá-lo ou transformá-los em e e passá-los.00input_name$3$4

Para executar, use , por exemplo ,../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

Você deve citar suas variáveis ​​de shell; especialmente os que provêm de argumentos ou outras informações do usuário: por exemplo, "./$input_pdf_name"e até seq 1 "$num_pages". Além disso, você pode querer mudar `…`para $(…)- veja isso , isso e isso .
G-Man diz 'Reinstate Monica'

Este é o script de OccamsRazor, exceto pelas alterações que observei. Eu não sou programador de shell, então não queria mexer com algo que funcionasse. Mas se alguém quiser limpar isso, você tem meus agradecimentos.
lowwall
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.