· 

PDFファイルの赤字を白に置き換える(Python)

(著)山たー

あまりにもニッチすぎるが役立ちそうだったので。誰かが作ったまとめPDFの赤字を全て白字に置き換えられれば勉強が捗る…はず。なおOSはWindows。MacやLinuxならもっと簡単にできたと思う。

 

結果

 先に結果を掲載しておく。やりたいことはこんな感じ。

 

 

手書きでもOK

 

 

これで重要なところを赤字で書き、スキャンして赤字を消せばノートが穴埋め問題集に早変わりする。iPadに赤シートを被せるという原始人みたいなことをする必要はない。ただし手書きだと若干汚くなる上、閾値の調節が面倒。

 

変換の手順

①pdf → 画像に変換

②画像の中の赤字を白に置換

③画像 → pdfに変換

 

Popplerのダウンロード

まずpdfを画像に変換する。OSがWindowsなのでやたらと手間取ったが、Popplerを使うことにした。Poppler for Windowsから"poppler-0.51_x86.7z"のような7zファイルをダウンロードして解凍し、適当なディレクトリに置く。今回はC:/Users/user/の下に置いた。popplerは解凍するだけで使える。

 

コード

ライブラリはpillowとPyPDF2が必要なので、pipで入れておく。

pip install pillow
pip install pypdf2
import subprocess
from PIL import Image
from PyPDF2 import PdfFileMerger
import os

def pdf_red2white(popplerpath,pdfpath,pdfpages,
                  outputname = "output", threshold = 200):
    """
    popplerpath: popplerのPATH
    pdfpath    : 変換したいpdfのPATH
    pdfpages   : 変換したいpdfのページ数
    outputname : 出力するpdfのファイル名(デフォルトはoutput.pdf)
    threshold  : 赤の閾値(値を小さくすると赤字が消えやすくなるが、全体的にかすれる)
    """
    
    #pdfを画像に変換
    subprocess.call([popplerpath+"pdftocairo.exe", "-png", pdfpath, "tmpimg"])
    
    #画像内の赤字を白に置換
    for i in range(1,pdfpages+1):
        img = Image.open('tmpimg-{0:01d}.png'.format(i))
        
        r, g, b = img.split()
        mask = r.point(lambda _: 1 if _ > threshold else 0, mode="1")
        img.paste(Image.new("RGB", img.size, (255,255,255)), mask=mask)
        img.save('tmp_img_white'+str(i)+'.pdf', 'PDF', quality=100, optimize=True)
        img.close()
    
    #pdfをマージ
    filelist = ('tmp_img_white'+str(i)+'.pdf' for i in range(1, pdfpages + 1))
    merger = PdfFileMerger()
    
    for file in filelist:
        merger.append(file)
    
    merger.write(outputname + '.pdf')
    merger.close()
    
    #中間ファイルを削除
    for i in range(1,pdfpages + 1):            
        os.remove('tmpimg-'+str(i)+'.png')
        os.remove('tmp_img_white'+str(i)+'.pdf')

if __name__ == "__main__":
    popplerpath = "C:/Users/user/poppler-0.51_x86/poppler-0.51/bin/" #popplerのpath
    pdfpath = "test.pdf" #pdfのpath
    pdfpages = 5 #前から5ページを変換
    pdf_red2white(popplerpath,pdfpath,pdfpages, threshold = 150)

途中出てくる中間ファイルはos.removeを使って削除している。

 

参考にしたサイト

こんなことしてる暇があったら普通に勉強したらどうなんですかね…。