Hogyan lehet nyomtatóbaráttá konvertálni egy PDF dokumentumot?

Az Arcanum Digitális Tudománytárban vagy a Hungaricana Könyvtárban kutatva sokszor színesben beszkennelt dokumentumokat találunk, amelyek kinyomtatva pazarolják a festéket és utána írni sem jó rájuk. Egy rövidke algoritmussal azonban fehér alapon fekete betűssé varázsolhatjuk a gépünkre lementett PDF fájlokban lévő oldalakat.

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. Mégpedig hagyományos, üveges tintával feltöltött tollal. 🙂 Táblagépen egészen más érzés olvasni és jegyzetelni. Én valahogy nem tudok megbarátkozni azzal.

Szóval 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!

# 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.

# 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.

# 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. 😃

comments powered by Disqus