はじめに
今更だがStreamlitという便利なものがあることを知ったので、勉強も兼ねて前に書いた「PythonでPDFに透かし(Watermark)を追加する」コードをStreamlitから呼び出して実行できるようにしてみた。
Streamlitはオープンソースのライブラリで、Pythonで簡単にウェブアプリを作ることができる。
処理の流れ
PythonのコードにStreamlit用のAPIを呼び出しておいて、そのPythonコードをStreamlitから走らせると、ブラウザで実行できるアプリの完成。
streamlit run test.py
手順
Streamlitのインストール
pip install streamlit
# pip install reportlab pypdf
ReportLabとpypdfのインストールは前回インストール済み。
前回のコードのモジュール化
import os
from pypdf import PdfReader
from pypdf import PdfWriter
import streamlit as st
def watermark_page(text, color, alpha, font, width, height, rotate):
from reportlab.pdfgen import canvas
import io
import math
#
font_size = width / len(text) * 1.7
rgb = [int(color[i:i+2], 16) / 255 for i in (1, 3, 5)]
cos = math.cos(math.radians(-1 * rotate))
sin = math.sin(math.radians(-1 * rotate))
x, y = (width * 0.5, height * 0.5)
x, y = (x * cos - y * sin, x * sin + y * cos)
buf = io.BytesIO()
can = canvas.Canvas(buf, (width, height))
can.rotate(rotate)
can.setFillColorRGB(*rgb)
can.setFillAlpha(alpha / 100) # transparency
can.setFont(font, font_size)
can.drawCentredString(x, y, text)
can.showPage()
can.save()
buf.seek(0)
return PdfReader(buf).pages[0]
def add_watermark(files, wm_text, wm_color, wm_alpha, wm_font, wm_rotate):
for file in files:
bar = st.progress(0, f'Processing {file.name}') # Streamlitのコマンド
writer = PdfWriter(clone_from=file)
width = writer.pages[0].mediabox.width # pt=1/72 inch
height = writer.pages[0].mediabox.height # pt=1/72 inch
wm_page = watermark_page(wm_text, wm_color, wm_alpha, wm_font, width, height, wm_rotate)
page_num = len(writer.pages)
for i, page in enumerate(writer.pages):
page.merge_page(wm_page, over=True)
bar.progress((i + 1) / page_num, f'Processing {file.name}') # Streamlitのコマンド
wm_fname = file.name.replace('.pdf', '_wm.pdf')
wm_fpath = os.path.expanduser(f'~\\Documents\{wm_fname}')
writer.write(wm_fpath)
前回作成したコードはまとめて関数にしておく、ついでに複数ファイルを処理できるように変更、透かし付きのPDFファイルはWindowsのDocumentsフォルダに作成するようにした。
ここで既にStreamlitのAPIのst.progressを使っている。
import streamlit as st
bar = st.progress(0, f'Processing {file.name}') # Streamlitのコマンド
bar.progress((i + 1) / page_num, f'Processing {file.name}') # Streamlitのコマンド
「bar = st.progress」でプログレス・バーを生成でき、「bar.progress」でバーを進めることができる。「st.progress」の引数は、バーの初期値と上に表示するテキスト。「bar.progress」を呼び出すごとにバーの値が更新されていく。
このコードではPDFページの処理の進み具合を表示するために利用。
if __name__ == '__main__':
st.subheader('Choose PDF files')
files = st.file_uploader('Choose PDF files', type=['pdf'], accept_multiple_files=True)
#
with st.container():
st.subheader('Watermark settings')
wm_text = st.text_input('Text', 'Confidential Document NDA only for XXX')
wm_font = st.selectbox('Font', ('Helvetica-Bold', 'Helvetica', 'Courier-Bold', 'Courier', 'Times-Roman', 'Times-Bold'))
wm_color = st.color_picker('Color', '#f90000')
wm_alpha = st.slider('Transperancy: 0=most', 0, 100, 40, 5)
wm_rotate = st.slider('Rotation', -180, 180, 30, 5)
#
st.subheader('Proceed')
with st.form('proceed'):
proceed = st.form_submit_button(label='Go')
if proceed:
add_watermark(files, wm_text, wm_color, wm_alpha, wm_font, wm_rotate)
