Sokan talán azt gondolják rólam, hogy mindenben a digitális megoldásokat preferálom. De ez nem így van. Amikor kutatási anyagokat olvasok, akkor azt szeretem, ha az adott dokumentum a fizikai valójában is ott van előttem, arra ráírhatok vagy aláhúzhatok benne valamit. Táblagépen egészen más érzés olvasni és jegyzetelni. Én valahogy nem tudok megbarátkozni azzal.

Szóval az ADT-ről vagy bárhonnan az internetről letöltött PDF dokumentumokat rendszerint ki akarom nyomtatni, de ez elé akadályt gördít, ha színesen vannak beszkennelve. Van rá ugyan lehetőség, hogy képként kiügyeskedjük a PDF fájlból az oldalakat, majd utána fekete-fehérré konvertáljuk őket. Ez azonban egy mechanikusan elvégzett, pepecselős munka. Néhány oldalnál nem probléma, de tömeges mennyiségű anyaggyűjtésnél egy idő után idegesítővé és frusztrálóvá válik.

Ez a pont a tegnapi napon jött el nálam. Már régebben eszembe jutott a folyamat automatizálásának lehetősége, de csak most szántam rá magam a megvalósításra. Őszintén szólva kár volt idáig várni vele, mert egész egyszerűen megoldhatónak bizonyult a dolog.

Az alábbiakban R nyelven (v4.1.2) írt kódot használok a feladat végrehajtásához. A magyarázó szövegek közé ékelt fekete kódblokkok tartalmát az RStudio-ban egymás alá illesztve elvileg bárki által reprodukálható az itt bemutatott műveletsor. A kódblokkok # kezdetű sorai pusztán magyarázó funkcióval bírnak, ezekre a program futtatásakor nincs szükség.

A feladat végrehajtásához a magick és az xopen csomagokat fogom használni. Az előbbivel tudjuk a képeket a PDF dokumentumból kivonni, fekete-fehérré konvertálni, majd visszaírni ugyanoda. Az utóbbi pedig arra szolgál, hogy ha akarjuk, akkor automatikusan megnyíljon majd a gépünkön az elkészült fájl. Egy adott függvény származási helyének egyértelmű beazonosításához a csomag::függvény() formulát használom a kódban. (A base csomag függvényei automatikusan betöltődnek, ezt nem jelölöm külön.)

Elöljáróban megemlítem még, hogy korábban egy részletes blogposztot írtam a PDF dokumentumok R nyelven történő manipulálásáról. Szükség esetén javaslom ennek tanulmányozását is.

Elsőként töltsük be a fenti csomagokat és hozzunk létre egy munkakönyvtárat a gépünkön!

1
2
3
4
5
6
7
8
# A szükséges csomagok betöltése.
# A legelső használat előtt az install.packages("...") utasítással telepíteni
# kell ezeket. A ... helyére az adott csomag neve írandó.
library(magick)
library(xopen)

# Ide a saját munkakönyvtárunk elérését kell beírni!
setwd("C:/Munkakönyvtár")

Az algoritmus a munkakönyvtárban fogja keresni az átalakítandó fájlokat, illetve ide menti el azokat, miután elkészült velük. Érdemes a böngésző alapértelmezett letöltési könyvtárát megadni. Ekkor a fájlok áthelyezésével sem kell foglalkozni, azonnal feldolgozhatók lesznek azok.

Hangsúlyozni szeretném azonban, hogy a munkakönyvtárban lévő valamennyi PDF dokumentumot feldolgozza az algoritmus! Vagyis egyszerre többel is elboldogul. Nincs jelentősége annak, hogy ezeket honnan töltöttük le, hogyan kerültek oda és mi az elnevezésük. Ami a munkakönyvtárban van, az átalakításra kerül. A felesleges PDF fájlokat tehát, beleértve a már átkonvertált dokumentumokat is, minden futtatás előtt el kell távolítanunk onnan.

A műveletet végrehajtó algoritmust függvényként definiáltam. Azaz lényegét tekintve becsomagoltam egy konvNyomt() elnevezésű kódblokkba. Erre két dolog miatt volt szükség. Egyrészt azért, hogy a futtatás során ne kelljen kijelölni a kód releváns részeit, hanem egyetlen sornyi kóddal elindítható legyen a program. Másrészt pedig a függvény paramétereként meg lehet mondani az algoritmusnak, hogy az átkonvertált fájlok megnyitódjanak-e automatikusan. Alapértelmezés szerint egyébként nem fognak, mert ha egyszerre sok fájlt konvertálunk, akkor nem feltétlenül szeretnénk ezzel terhelni a rendszert.

Lássuk tehát ezt a függvényt! A további magyarázatot beleírtam az alábbi kódblokkba.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# A függvény definiálása konvNyomt néven.
# A megnyitas nevű paramétere alapértelmezetten hamis.
konvNyomt <- function(megnyitas = FALSE){
  # Információk begyűjtése a munkakönyvtárunkban lévő PDF fájlokról.
  # Egy adatkeretet kapunk, amelynek minden sora egy-egy fájlnak felel meg.
  pdfDokumentumok <- file.info(list.files(pattern="pdf"))
  # Az adatkeret sorainak neve megegyezik a PDF fájlok nevével.
  # Ezeket átmásoljuk egy vektorba.
  pdfDokumentumok <- rownames(pdfDokumentumok)
  # Egyenként végig megyünk a vektor elemein, vagyis feldolgozzuk a PDF fájlokat.
  for (i in pdfDokumentumok) {
    # Az éppen feldolgozás alatt álló dokumentum nevének kiírása a konzolra.
    # Ha több fájlt dolgozunk fel, akkor ennek alapján látjuk, hogy éppen hol tartunk.
    print(i)
    # A képek kivonása az aktuális PDF dokumentumból.
    oldalKepek <- magick::image_read_pdf(path = i)
    # A képek fekete-fehérré konvertálása.
    oldalKepek <- magick::image_convert(image = oldalKepek, type = "Bilevel")
    # Az eredeti PDF dokumentum felülírása az átkonvertált képekkel.
    magick::image_write(image = oldalKepek, path = i, format = "pdf")
    # Ha a függvény megnyitas nevű paramétere igaz, 
    # akkor a számítógépen megnyílik az adott PDF dokumentum.
    if (megnyitas) {
      xopen::xopen(i)
    }
  }
}

Az iménti kódblokk tartalmát az adott munkafolyamat során csak egyszer kell lefuttatni! Ezt követően a konvNyomt() néven hivatkozhatunk rá minden olyan alkalommal, amikor el akarunk indítani egy konvertálást.

A függvényünk alapértelmezett paramétere a FALSE. Ezzel nem fognak automatikusan megnyílni az átkonvertált PDF fájlok. Ha mégis szeretnénk megnyitni azokat, akkor a TRUE paramétert kell használnunk.

Megemlítem még, hogy az általunk definiált konvNyomt() függvényt a suppressMessages() nevű függvény paramétereként adtam meg. Ez elrejti azokat a hibaüzeneteket, amelyek egyébként nincsenek befolyással a kód működésére, de esetleg zavaróak lehetnek.

1
2
# A konvNyomt nevű függvény meghívása.
suppressMessages(konvNyomt(FALSE))

A fentieket összegezve a teendő tehát a következő:

  1. Munkamenetenként egyetlen alkalommal lefuttatjuk az első és a második kódblokk tartalmát.

  2. Ezt követően már csak a harmadik kódblokkal kell foglalkoznunk. Ezzel tudjuk elindítani a munkakönyvtárunkban aktuálisan megtalálható PDF fájlok átkonvertálását. Itt lehet beállítani a FALSE vagy TRUE értéket az automatikus megnyitáshoz. A legkönnyebben úgy lehet lefuttatni ezt a kódrészletet, ha a kurzorral beleállunk az adott sorba, majd a Ctrl+Enter billentyűkombinációt használjuk.

Íme egy példa a végeredményre:

Egy adott oldal képe a fekete-fehérré konvertálás előtt és után

Egy adott oldal képe a fekete-fehérré konvertálás előtt és után (forrás)

Ezzel készen is vagyunk. Ahogy fentebb látható, egészen szép eredményt kaptunk. Ez azonban nagyban függ az átkonvertálandó anyagtól. Ha a beszkennelt oldal eredetije silány minőségű papírra van nyomtatva, esetleg nagyon gyűrött vagy hajtogatott, akkor elképzelhető, hogy a végeredmény nem lesz a várakozásainknak megfelelő. Emellett nagyon ritkán olyat is tapasztaltam, hogy egy teljesen fehér oldal keletkezett. De ezek az extrém eset kategóriájába tartoznak. Alapvetően egy nagyon hasznos kis algoritmus ez. 😃