web-dev-qa-db-fra.com

Rogner aléatoirement les fichiers pdf et l'image de sortie

J'ai plusieurs fichiers pdf dans un dossier. Tout ce que je veux faire est de charger un fichier pdf et de générer 100 cultures aléatoires à partir de celui-ci et de convertir chaque culture en image de taille 256x256. Donc, si j'ai 100 fichiers PDF, j'aurai 100 images jpg en sortie, car je veux obtenir 100 récoltes à partir de 100 fichiers PDF dans un dossier. Ce processus peut-il être automatisé? Les fichiers pdf sont des articles de revues scientifiques de CiteSeerX. J'ai fourni un exemple de document .

Je voudrais aussi que le recadrage aléatoire se concentre sur les lieux contenant des textes plutôt que sur les régions avec un fond blanc. Puis-je appliquer cela en utilisant certaines techniques?

4
Dharma

Vous aurez besoin des utilitaires Ghostscript, Poppler et ImageMagick:

Sudo apt install ghostscript poppler-utils imagemagick

Passons en revue cette étape par étape (parce que j'ai besoin de passer moi-même par ce processus mental).

Extraire une page au hasard d'un PDF

pagecount=$(pdfinfo in.pdf | sed -ne 's/^Pages:\s*//p')
page=$(($RANDOM % $pagecount + 1))
gs -q -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -sDEVICE=pdfwrite \
  -dFirstPage="$page" -dLastPage="$page" -sOutputFile="in.$page.pdf" -f in.pdf

Recadrer une section prédéfinie de la même page

gs -q -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -sDEVICE=pdfwrite \
  -c "[/CropBox [50 50 250 250] /PAGES pdfmark" \
  -sOutputFile=out.pdf -f "in.$page.pdf"

Recadrer une section aléatoire de la même page

Sélectionnez une valeur décimale pour cropsize (en points , 1 point = 1/72 pouce) inférieure à la largeur et à la hauteur.

cropsize=50
bbox=$(gs -q -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -sDEVICE=bbox -f "in.$page.pdf" 2>&1 >&- | sed -ne 's/^%%HiResBoundingBox:\s*//p')

cropbbox=$(python3 - "$cropsize" "$bbox" <<EOF
import sys, random
cropsize = float(sys.argv[1])
llx, lly, urx, ury = map(float, sys.argv[2].split(None, 3))
width = urx - llx
height = ury - lly
if width < cropsize or height < cropsize:
    print('Crop size too small for bounds', llx, lly, urx, ury, file=sys.stderr)
    sys.exit(1)

cropllx = random.uniform(0, width - cropsize) + llx
croplly = random.uniform(0, height - cropsize) + lly
cropurx = cropllx + cropsize
cropury = croplly + cropsize
print(*map(lambda x: format(x, '.6f'), (cropllx, croplly, cropurx, cropury)))
EOF
)

gs -q -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -sDEVICE=pdfwrite \
  -c "[/CropBox [$cropbbox] /PAGES pdfmark" \
  -sOutputFile=cropped.pdf -f "in.$page.pdf"

Convertir un PDF recadré en JPEG

Ajustez size, -density (DPI pour le rendu du PDF) et -quality (qualité de la compression JPEG) à vos besoins.

size=256
convert -define pdf:use-cropbox=true -colorspace sRGB -density 600 cropped.pdf \
-flatten -resize "${size}x${size}^" -crop "${size}x${size}+0+0!" -quality 75% cropped.jpg

Rassembler tout cela: Couper N sections aléatoires à partir d'une quantité arbitraire de PDF

Le résultat est un peu lourd pour l'inclusion en ligne. Par conséquent, vous devez télécharger crop.sh et crop-calc.pyde mon répertoire dans le même répertoire.

Usage:

bash /path/to/crop.sh [OPTIONS...] <N> <PDF...>

avec:

  • N - le nombre de zones aléatoires à extraire par document

  • PDF... - un nombre quelconque de fichiers PDF

  • -s|--size PX - taille des images résultantes en pixels (256 par défaut)

  • -c|--cropsize PT - taille des régions du document à rogner en points (50 par défaut)

  • -d|--density DPI - densité de pixels lors du rendu du document (600 par défaut)1

  • -q|--quality Q - qualité de compression de l'image obtenue, généralement en pourcentage (valeur par défaut de 75%)

  • --destext EXT - l'extension de fichier (et le format) des images résultantes (par défaut jpg)


1 ImageMagick définit une limite stricte de 500 mio. pixels qui signifie pour une zone carrée la valeur de cropsize 72 ⋅ density ne doit pas dépasser √500 mio.

3
David Foerster