end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

reportlab & pypdf for python を用い、pdfに文字列や図形を透明(透かし)で追加

from pypdf import PdfReader, PdfWriter
from reportlab.pdfgen  import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.colors      import red,black
import io
import sys

def main():
    org_pdf_path = sys.argv[1]
    new_pdf_path = "new.pdf"

    # https://moji.or.jp/ipafont/ipafontdownload/
    pdfmetrics.registerFont(TTFont("IPAexGothic", "./ipaexg.ttf"))
    
    pdf_reader = PdfReader( open(org_pdf_path, "rb") )
    pdf_writer = PdfWriter()

    for page in pdf_reader.pages:
        page = add_object_to_page(page)
        
        pdf_writer.add_page(page)

    # Write the modified PDF to a new file
    with open(new_pdf_path, "wb") as output_file:
        pdf_writer.write(output_file)

def add_object_to_page(page):
    packet = io.BytesIO()
    can = canvas.Canvas(packet,
                        pagesize=(page.mediabox.width,
                                  page.mediabox.height))
    tmp_txt = """
reportlab を用い、pdfへ図形や文字列を追加しています。
reportlab を用い、pdfへ図形や文字列を追加しています。
reportlab を用い、pdfへ図形や文字列を追加しています。
reportlab を用い、pdfへ図形や文字列を追加しています。
    """
    can.setFont("IPAexGothic", 10)
    can.setFillColor(red, alpha=0.4)    # alpha=0.0にすると透明

    # drawString()は 1行で出力
    can.drawString(10, page.mediabox.height - 30, tmp_txt)

    # 複数行をまとめて出力する場合、
    textobject = can.beginText(10, page.mediabox.height - 50)
    textobject.setFont("IPAexGothic", 10)
    textobject.textLines(tmp_txt)
    can.drawText(textobject)
    
    # # alpha=0に近い程,透明
    # can.setFillColorRGB(0.5, 0.5, 0.5, alpha=0.95)
    # can.rect(20,20,                     # 左下座標
    #          page.mediabox.width-40,    # 幅
    #          page.mediabox.height-40,   # 高
    #          fill=True)
    can.save()

    # move to the beginning of the StringIO buffer
    packet.seek(0)
    new_pdf = PdfReader(packet)

    # merge the rectangle with the page
    page.merge_page(new_pdf.pages[0] )
    return page

if __name__ == "__main__":
    main()