[gelöst] Bilder ohne gescannte Seiten aus PDF extrahieren

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
reox
Beiträge: 2529
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz

[gelöst] Bilder ohne gescannte Seiten aus PDF extrahieren

Beitrag von reox » 06.10.2021 21:22:59

Ich möchte ein Script schreiben, dass aus einer Sammlung von PDFs alle Bilder (also zB Diagramme) extrahiert. pdfimages aus Debianpoppler-utils kann das sehr gut aber man kann keine filter angeben welche Bilder genau extrahiert werden.
zB habe ich einige PDFs die im Endeffekt aus eingescannten Seiten bestehen, das schaut zB so aus:

Code: Alles auswählen

$ pdfimages -l 10 -list files/some.pdf
page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
   1     0 image    1339  1922  icc     3   8  jpeg   no        18  0   201   201 59.0K 0.8%
   2     1 stencil  3760  3988  -       1   1  jbig2  no        27  0   600   600 2708B 0.1%
   3     2 stencil  4016  5764  -       1   1  jbig2  no        42  0   600   600 11.4K 0.4%
   4     3 stencil  4016  4290  -       1   1  jbig2  no        48  0   600   600 9.80K 0.5%
So ganz genau weiß ich auch nicht wie man das erkennen kann ob es eine gescannte seite ist * - aber mir scheint zumindest, dass type "stencil" eher weniger als grafiken in PDFs verwendet werden.
Ich hab gelesen, die einzige methode wie man mit pdfimages filtern kann ist 1) alles extrahieren und dann 2) mit -list alles filtern und wieder löschen.
Das ist mir aber eigentlich zu doof, weil pdfimages ist jetzt auch nicht das schnellste tool ;)

Hat jemand eine andere idee?


* nach anschauen einiger PDFs, schauts so aus als ob stencil kein alleiniges merkmal ist... bei einem anderen ist es type image. Außerdem gibt es einige verschiedene typen wie jbig2, ccit oder jpeg.
vermutlich ist die aufgabe daher doch schwerer als gedacht. Aber ggf muss man einfach nur irgendwie nach der größe filtern und vorher die page size auslesen oder so...
Zuletzt geändert von reox am 07.10.2021 21:40:29, insgesamt 1-mal geändert.

Benutzeravatar
Blackbox
Beiträge: 4289
Registriert: 17.09.2008 17:01:20
Lizenz eigener Beiträge: GNU Free Documentation License

Re: Bilder ohne gescannte Seiten aus PDF extrahieren

Beitrag von Blackbox » 06.10.2021 22:08:08

reox hat geschrieben: ↑ zum Beitrag ↑
06.10.2021 21:22:59
Hat jemand eine andere idee?
Schau dir einmal die Pakete: Debianpdfarranger und Debianpdfshuffler an.
Eigenbau PC: Debian Sid - Kernel: 6.5.13 - Xfce 4.18 mit sway
Desktop PC: Dell Inspiron 530 - Debian Sid - Kernel: 6.5.13 - Xfce 4.18 mit sway
Notebook: TUXEDO BU1406 - Debian Sid - Kernel: 6.5.13 - Xfce 4.18 mit sway
Alles Minimalinstallationen und ohne sudo/PA/PW.
Rootserver: Rocky Linux 9.3 - Kernel: 5.14

Freie Software unterstützen, Grundrechte stärken!

Benutzeravatar
schorsch_76
Beiträge: 2601
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: Bilder ohne gescannte Seiten aus PDF extrahieren

Beitrag von schorsch_76 » 06.10.2021 22:12:01

Ich denke, es kommt auch darauf an, wie deine PDFs die Bilder und den Text gespeichert haben. Es kann auch Text als Bitmap gespeichert sein. Da wird der Ursprung der Daten eine Rolle spielen.

https://en.m.wikipedia.org/wiki/PDF
Wikipedia hat geschrieben: A PDF file is often a combination of vector graphics, text, and bitmap graphics. The basic types of content in a PDF are:

Text stored as content streams (i.e., not encoded in plain text);
Vector graphics for illustrations and designs that consist of shapes and lines;
Raster graphics for photographs and other types of images
Multimedia objects in the document.

reox
Beiträge: 2529
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz

Re: Bilder ohne gescannte Seiten aus PDF extrahieren

Beitrag von reox » 07.10.2021 07:13:58

Blackbox hat geschrieben: ↑ zum Beitrag ↑
06.10.2021 22:08:08
reox hat geschrieben: ↑ zum Beitrag ↑
06.10.2021 21:22:59
Hat jemand eine andere idee?
Schau dir einmal die Pakete: Debianpdfarranger und Debianpdfshuffler an.
seh ich jetzt nicht adhoc wie ich das verwenden kann:
PDF-Shuffler is a small python-gtk application, which helps the user to merge or split pdf documents and rearrange their pages using an interactive and intuitive graphical interface.
aber vllt ists eh einfacher sich ein python script zu schreiben:
PDF-Shuffler is a frontend for python-pyPdf.
schorsch_76 hat geschrieben: ↑ zum Beitrag ↑
06.10.2021 22:12:01
Ich denke, es kommt auch darauf an, wie deine PDFs die Bilder und den Text gespeichert haben. Es kann auch Text als Bitmap gespeichert sein. Da wird der Ursprung der Daten eine Rolle spielen.
Ja, eine optimale Lösung gibt es dafür sicher nicht aber eine Heuristik würde schon reichen.
Es geht einfach darum aus einer Kollektion an Wiss. Artikeln alle Bilder zu holen, um dann einfach durchscrollen zu können. Oft weiß man noch so ca, dass es da mal was gab - aber nicht mehr welches paper es genau war. An Grafiken erinnere (zumindest ich) mich leichter als an Titel.
Die paper kommen von diversen Journalen und wie mir scheint fast alles vor 1990 (eher sogar vor 2010...) besteht aus eingescannten Seiten. Bis jetzt hab ich da auch schon ganz merkwürdige Verfahren gesehen, wo die Seite in Blöcke geteilt ist und dann immer diese Blöcke als Bild raus kommen... Ich glaub wenn man ganz viel Spaß hat, könnt man sich ein kleines neuronales Netz trainieren, was Diagramme von Text unterscheidet :)

katzenfan
Beiträge: 645
Registriert: 19.04.2008 22:59:51

Re: Bilder ohne gescannte Seiten aus PDF extrahieren

Beitrag von katzenfan » 07.10.2021 09:16:00

Sind das eigene PDF und eigene Bilder? Andernfalles könnte die vorherige Beschäftigung mit dem Urheberrecht bzw. dem Recht am eigenen Bild sehr nützlich sein; unionsrechtlich hat sich beides im Laufe der Jahre verschärft.

reox
Beiträge: 2529
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz

Re: Bilder ohne gescannte Seiten aus PDF extrahieren

Beitrag von reox » 07.10.2021 16:46:27

katzenfan hat geschrieben: ↑ zum Beitrag ↑
07.10.2021 09:16:00
Sind das eigene PDF und eigene Bilder? Andernfalles könnte die vorherige Beschäftigung mit dem Urheberrecht bzw. dem Recht am eigenen Bild sehr nützlich sein; unionsrechtlich hat sich beides im Laufe der Jahre verschärft.
In wie weit ist das für mich relevant? Ich wüsste nicht, warum ich das PDF nicht zerschneiden darf? Wie gesagt, es handelt sich dabei um Wissenschaftliche Publikationen - viele davon auch Open Access (mit diversen Lizenzen) - und die extrahierten Bilder verlassen meinen eigenen PC nicht und sind auch nur für mich zum Auffinden der paper da.

katzenfan
Beiträge: 645
Registriert: 19.04.2008 22:59:51

Re: Bilder ohne gescannte Seiten aus PDF extrahieren

Beitrag von katzenfan » 07.10.2021 18:54:37

reox hat geschrieben: ↑ zum Beitrag ↑
07.10.2021 16:46:27
In wie weit ist das für mich relevant? Ich wüsste nicht, warum ich das PDF nicht zerschneiden darf?
Im Unionsrecht bestimmt allein der Urheber eines Werkes, egal ob Literatur, Kunst oder sonstwas, wer sein Werk wie und auf welche Weise verwenden darf.

Nenne mir eine nicht auf Software bezogene Lizenz, die das Zerpflücken des Werkes gestattet.

reox
Beiträge: 2529
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz

Re: Bilder ohne gescannte Seiten aus PDF extrahieren

Beitrag von reox » 07.10.2021 20:14:29

zB viele Open Access Journals veröffentlichen unter CC-BY und da steht "transform" mit dabei. Die Attributierung des Schnipels sicherzustellen ist trivial.

reox
Beiträge: 2529
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz

Re: Bilder ohne gescannte Seiten aus PDF extrahieren

Beitrag von reox » 07.10.2021 21:39:21

Hab mich mal hingesetzt und mit pymupdf ein kleines script gebaut:

Code: Alles auswählen

from io import BytesIO
import logging
import os

import click
import fitz
from PIL import Image
import tqdm
from tqdm.contrib.logging import logging_redirect_tqdm


logging.basicConfig(level='INFO')

logger = logging.getLogger("main")


@click.command()
@click.option('--epsilon', default=1.0, help="size in mm to which mediabox and image size can be equal")
@click.argument('filename')
def cli(filename, epsilon):
    """
    Extract all images from a PDF and stores them to a folder relative to the document
    """
    bname = os.path.splitext(filename)[0]
    with fitz.open(filename) as pdf:
        with logging_redirect_tqdm():
            for page in tqdm.tqdm(pdf, desc='loading pages'):
                _x, _y = page.mediabox_size / 72 * 25.4  # Convert from pt to mm
                logger.debug(f"Page {page.number}: x={_x:.2f}mm, y={_y:.2f}mm")

                for image in page.get_image_info(xrefs=True):
                    xref = image['xref']
                    # get size of image on page:
                    x0, y0, x1, y1 = image['bbox']
                    x = (x1 - x0) / 72 * 25.4
                    y = (y1 - y0) / 72 * 25.4

                    if abs(x - _x) < epsilon or abs(y - _y) < epsilon:
                        logger.debug("found image which is approx the same size as the page. skipping...")
                        continue

                    im_data = pdf.extract_image(xref)
                    logger.info(f"found image on page {page.number + 1} with size x={x:.2f}mm, y={y:.2f}mm of type {im_data['ext']!r}")
                    
                    
                    dfile = os.path.join('images', f"{bname}-{page.number:04d}-{xref:04d}.png")
                    folder = os.path.dirname(dfile)
                    if not os.path.isdir(folder):
                        os.makedirs(folder)
                    logger.debug("Saving file to %s", dfile)

                    Image.open(BytesIO(im_data['image'])).save(dfile)


if __name__ == "__main__":
    cli()
Das tuts für mich. Filter kann man da ja einbauen wie man will

Antworten