pdfからpngへ変換スクリプト.py
from pathlib import Path
import argparse
import systry:
import fitz # PyMuPDF
except ImportError:
print("PyMuPDF が見つかりません。先に以下を実行してください。")
print("python -m pip install PyMuPDF")
sys.exit(1)
def collect_pdfs(input_path: Path, recursive: bool) -> list[Path]:
if input_path.is_file():
if input_path.suffix.lower() == ".pdf":
return [input_path]
raise ValueError("指定されたファイルはPDFではありません。")if input_path.is_dir():
pattern = "**/*.pdf" if recursive else "*.pdf"
return sorted(input_path.glob(pattern))raise FileNotFoundError(f"入力パスが存在しません: {input_path}")
def get_output_file(
pdf_path: Path,
output_root: Path,
base_input_dir: Path | None,
page_no: int,
page_count: int,
) -> Path:
"""
元PDFのファイル名を保ったままPNG名を作る。1ページPDF:
sample.pdf -> sample.png複数ページPDF:
sample.pdf -> sample_page001.png
sample_page002.png
"""# サブフォルダ構造は維持する
if base_input_dir and pdf_path.is_relative_to(base_input_dir):
relative_parent = pdf_path.parent.relative_to(base_input_dir)
output_dir = output_root / relative_parent
else:
output_dir = output_rootoutput_dir.mkdir(parents=True, exist_ok=True)
if page_count == 1:
filename = f"{pdf_path.stem}.png"
else:
filename = f"{pdf_path.stem}_page{page_no:03d}.png"return output_dir / filename
def render_pdf_to_png(
pdf_path: Path,
output_root: Path,
base_input_dir: Path | None,
dpi: int,
overwrite: bool,
):
zoom = dpi / 72
matrix = fitz.Matrix(zoom, zoom)try:
doc = fitz.open(pdf_path)
except Exception as e:
print(f"[失敗] 開けません: {pdf_path} / {e}")
returnif doc.is_encrypted:
print(f"[スキップ] パスワード付きPDF: {pdf_path}")
doc.close()
returnprint(f"[処理開始] {pdf_path} ページ数: {doc.page_count}")
for page_index in range(doc.page_count):
page_no = page_index + 1output_file = get_output_file(
pdf_path=pdf_path,
output_root=output_root,
base_input_dir=base_input_dir,
page_no=page_no,
page_count=doc.page_count,
)if output_file.exists() and not overwrite:
print(f" [スキップ] 既に存在: {output_file}")
continuetry:
page = doc.load_page(page_index)
pix = page.get_pixmap(
matrix=matrix,
alpha=False,
annots=True,
)
pix.save(output_file)
print(f" [OK] {output_file}")
except Exception as e:
print(f" [失敗] page {page_no}: {e}")doc.close()
def main():
parser = argparse.ArgumentParser(
description="PDFをPNGに一括変換します。元PDFのファイル名を保って出力します。"
)
parser.add_argument(
"input",
help="PDFファイル、またはPDFが入っているフォルダ",
)
parser.add_argument(
"-o",
"--output",
default="png_output",
help="PNG出力先フォルダ。省略時は png_output",
)
parser.add_argument(
"--dpi",
type=int,
default=200,
help="出力解像度。通常は200、図面や細かい文字は300推奨",
)
parser.add_argument(
"-r",
"--recursive",
action="store_true",
help="サブフォルダ内のPDFも対象にする",
)
parser.add_argument(
"--overwrite",
action="store_true",
help="既存PNGを上書きする",
)args = parser.parse_args()
input_path = Path(args.input).expanduser().resolve()
output_root = Path(args.output).expanduser().resolve()
output_root.mkdir(parents=True, exist_ok=True)base_input_dir = input_path if input_path.is_dir() else None
try:
pdf_files = collect_pdfs(input_path, args.recursive)
except Exception as e:
print(f"[エラー] {e}")
sys.exit(1)if not pdf_files:
print("PDFが見つかりませんでした。")
sys.exit(0)print(f"対象PDF数: {len(pdf_files)}")
print(f"出力先: {output_root}")
print(f"DPI: {args.dpi}")
print("-" * 60)for pdf_path in pdf_files:
render_pdf_to_png(
pdf_path=pdf_path,
output_root=output_root,
base_input_dir=base_input_dir,
dpi=args.dpi,
overwrite=args.overwrite,
)print("-" * 60)
print("完了しました。")
if __name__ == "__main__":
main()
pdfからpngへ変換スクリプト実行.bat
※SHIFT-JIS (ANSI)で保存
pushd %~dp0
set filepath=%CD%
popd
echo %filepath%
pause
python pdfからpngへ変換スクリプト.py %filepath% -o %filepath%\pngs --dpi 300
pause



















