Community이미지github.com

shlomsh/scanned-pdf-cleaner

휴대폰 사진이나 거칠게 스캔한 책 페이지/학술 논문을 깨끗한 인쇄물 형태의 PDF로 변환합니다. 휘어진 선, 기울어진 페이지, 손가락, 제본 그림자, 페이지 컬, 이웃 페이지 조각, 얼룩, 여백 필기 등을 제거하고 텍스트, 그림, 캡션, 페이지 번호는 유지하며 여백을 균일하게 만듭니다.

scanned-pdf-cleaner란 무엇인가요?

이 스킬은 휴대폰으로 찍은 책 페이지나 불량 스캔본(사진 또는 PDF)을 읽기 쉬운 깨끗한 인쇄물 형태의 PDF로 변환하는 전문 이미지 처리 파이프라인입니다. 사용자는 각 페이지의 네 모서리를 수동으로 지정하고, 텍스트 블록 외부에 있는 어두운 표시(인쇄물인지 필기/얼룩인지)를 판단하여 '유지' 또는 '제거'를 결정합니다. 스크립트는 자동으로 페이지를 평평하게 펴고, 휘어진 선을 곧게 펴며, 종이를 흰색으로, 잉크를 검은색으로 보정하고, 손가락, 제본 그림자, 이웃 페이지 조각, 얼룩, 여백 필기 등 원치 않는 요소를 제거합니다. 최종 출력은 모든 페이지의 텍스트 크기와 여백이 일관된 하나의 균일한 PDF 파일로, 원본 파일 옆에 `_clean.pdf` 형태로 저장됩니다. 이 스킬은 Claude Code와 같은 터미널 기반 AI 어시트스턴트를 위해 설계되었으며, Python 가상 환경과 PIL, NumPy 등 일부 패키지를 필요로 합니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/shlomsh/scanned-pdf-cleaner/tree/HEAD/plugins/scanned-pdf-cleaner/skills/scanned-pdf-cleaner

Installed? Explore more 이미지 skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

스캔된 PDF 클리너

펼친 책을 휴대폰으로 찍으면 제본 부근이 휘어지고, 기울어지며, 회색빛이 돌고, 가장자리에 엄지손가락과 다음 페이지 조각이 보입니다. 이 스킬은 그러한 페이지를 깨끗한 인쇄물처럼 읽을 수 있는 페이지로 바꿉니다.

스크립트는 픽셀 작업을 합니다. 사용자는 판단을 내립니다. 각 페이지의 모서리를 추적하고, 제거된 부분을 확인하며, 텍스트 바깥의 표시 중 인쇄된 것(유지)과 그렇지 않은 것(제거)을 결정합니다. 각 단계는 이미지로 읽을 수 있는 콘택트 시트를 작성하므로, 이를 확인하세요. 단계가 작동했다고 가정하지 마십시오.

설정 (머신당 한 번)

SKILL=<이 스킬이 있는 폴더>      # 이 SKILL.md 파일이 들어 있는 폴더
python3 -m venv ~/.cache/scanned-pdf-cleaner-venv
~/.cache/scanned-pdf-cleaner-venv/bin/pip install -q -r "$SKILL/requirements.txt"
PY=~/.cache/scanned-pdf-cleaner-venv/bin/python

아래 모든 명령은 cd "$SKILL/scripts" && $PY <스크립트> ... 로 실행합니다. 문서당 하나의 비어 있는 새 작업 폴더를 사용하고, 사용자 프로젝트 외부(스크래치 또는 임시 폴더)에 만듭니다. 사용자의 파일은 읽기만 합니다.

워크플로우

1. 준비

$PY prepare.py INPUT.pdf WORK          # 또는: 이미지 폴더, 또는 이미지 파일 (HEIC는 먼저 변환)

WORK/src/p-NNN.jpg(바로 선 사진), WORK/grid/g-NNN.jpg(각 사진에 100px 간격의 빨간 격자, 네 모서리에 백 단위 레이블), 그리고 WORK/rough.json(사진당 임시 윤곽선 포함)을 작성합니다.

사진이 옆으로 또는 거꾸로 되어 있으면 돌립니다: $PY prepare.py --turn WORK p-003.jpg 90|180|270 (시계 방향).

2. 페이지 모서리 추적 (사용자)

모든 격자 이미지를 읽습니다. 각 사진에서 문서에 속하는 페이지를 찾습니다. 네 모서리를 소스 픽셀 단위로 WORK/rough.json에 기록하며, 순서는 페이지가 읽히는 대로 왼쪽 위, 오른쪽 위, 오른쪽 아래, 왼쪽 아래입니다. 격자 레이블이 가로 7, 세로 12이면 [700, 1200]으로 기록합니다.

{"001": {"src": "p-000.jpg", "quad": [[96,72],[930,92],[945,1468],[70,1480]]}}
  • 키는 출력 페이지 순서(001, 002, ...)입니다. 그 순서를 읽는 순서와 일치시키세요.
  • 페이지의 종이 가장자리를 기준으로 하며, 텍스트가 아닙니다. 제본 부근에서는 페이지가 안쪽으로 휘어지는 선을 기준으로 합니다. 사진 밖으로 나가는 페이지는 모서리를 사진의 가장자리에 둡니다.
  • 양면 페이지 사진은 같은 src를 가진 두 항목(페이지당 하나)을 만듭니다. 예: "005"와 "006".
  • 약 30픽셀 이내면 충분합니다. 다음 단계에서 실제 가장자리로 스냅합니다.

3. 종이 가장자리에 스냅

$PY refine.py WORK

WORK/quads.json과 WORK/sheets/quads-NN.jpg를 작성합니다. 주황색 = 사용자 추적, 빨간색 = 스냅됨, 녹색 점 = 왼쪽 위. 시트를 읽습니다. 빨간 윤곽선이 그림자, 테이블 또는 이웃 페이지 위로 점프했다면 해당 추적을 수정하고 단계를 다시 실행합니다.

4. 평평하게 펴기, 색조 보정 및 가장자리 정리

$PY clean.py WORK            # 또는: clean.py WORK 004 007  특정 페이지만 다시 수행

각 페이지에 대해 다음을 수행합니다:

  • 텍스트 줄과 양쪽 정렬된 컬럼 가장자리를 찾습니다.
  • 텍스트 블록을 직사각형으로 만들고 모든 줄에 하나의 부드러운 곡면을 맞춰 휘어진 줄이 곧게 나오도록 합니다.
  • 종이는 흰색으로, 잉크는 검은색으로 보정합니다.
  • 페이지 가장자리에 닿는 어두운 표시(손가락, 제본 컬, 주름, 다음 페이지 조각)를 제거합니다.

텍스트 줄이 5개 미만인 페이지(예: 제목 페이지, 전체 그림 페이지)는 대신 평범한 네 모서리 워핑을 적용합니다. 출력: WORK/pages/, WORK/blocks.json, WORK/sheets/review-NN.jpg. 여기서 빨간색 = 제거됨, 파란색 = 사용자 결정을 위해 남김, 녹색 = 텍스트 블록.

리뷰 시트를 읽습니다. 확인할 사항:

  • 여전히 휘어져 있거나 페이지가 기울어져 있음: 추적이 잘못되었습니다. rough.json을 수정한 후 해당 페이지에 대해 refine과 clean을 다시 실행하세요.
  • 녹색 상자 안에 빨간색으로 표시된 텍스트: 사용자에게 알리세요. 가장자리 정리는 텍스트 블록 안에 있는 텍스트를 제거하지 않습니다(페이지 가장자리 띠에 있지 않은 한).

5. 텍스트 외부 표시 목록 작성

$PY flags.py WORK

WORK/flags/flags-N.jpg를 작성합니다. 텍스트 블록 외부에 있는 모든 어두운 표시의 번호가 매겨진 타일입니다.

6. 유지 또는 제거 결정 (사용자)

플래그 시트를 읽고 WORK/decisions.json을 작성합니다:

{"keep": [0, 3, 4, 7], "strokes_only": [23], "erase": [{"page": "014", "box": [1500, 300, 80, 900], "mode": "strokes"}]}
  • keep: 인쇄된 모든 것. 페이지 번호, 러닝 헤드, 장 번호, 캡션, 사이드 레이블, 표 규칙, 그림 및 드로잉이 포함됩니다. 인쇄된 글자는 선명하고 규칙적입니다. 책 속의 그림도 인쇄물입니다(아이들이 그린 낙서 같아도).
  • remove: 숫자를 목록에서 빼세요. 필기, 펜 및 연필 메모, 얼룩, 점, 지문, 회색 막대, 찢어진 가장자리 그림자가 포함됩니다. 펜 선은 가늘고 고르지 않으며 종종 기울어져 있고 글꼴과 일치하지 않습니다.
  • strokes_only: 인쇄된 글자에 펜 선이 지나가거나 옆에 있는 것. 1.5줄보다 긴 선만 제거됩니다.
  • erase: pages/page-KEY.jpg의 페이지 픽셀 단위 상자로, 텍스트 블록 안에 있으면서 제거하라고 요청된 표시를 위한 것입니다. "mode": "all"은 상자를 하얗게 만들고, "strokes"는 긴 선만 제거합니다.

사용자가 원할 수 있는 것을 제거하기 전에 물어보세요. 여기에는 텍스트 안의 밑줄이나 줄 사이 메모, 형광펜이 포함됩니다. 기본값: 여백 메모는 제거, 텍스트 안의 밑줄은 유지. 인쇄물과 필기를 구분할 수 없을 때도 물어보세요. 타일을 보여주고 설명하지 마세요.

7. 마무리

$PY finish.py WORK OUT.pdf           # --no-frame은 각 페이지의 자체 프레임 유지; --dpi 300이 기본값

수행하는 작업:

  • 유지 항목을 제외한 텍스트 블록 외부의 모든 것을 하얗게 만듭니다.
  • 블록 옆에 붙어 있는 길고 얇은 펜 브래킷을 제거합니다.
  • 모든 페이지를 하나의 페이지 크기에 프레임합니다:
    • 텍스트는 하나의 크기로 나옵니다. 가깝거나 멀리서 찍은 사진이 일치합니다. 스케일링은 텍스트 블록의 너비를 사용하거나, 그림이 컬럼을 좁히는 경우 줄 간격을 사용합니다.
    • 측면 여백은 동일하므로, 한쪽 가장자리에 붙어 있거나 책 두께로 인해 중앙에서 벗어난 내용이 중앙에 배치됩니다.
    • 모든 페이지는 동일한 위쪽 여백에서 시작합니다.

전달하기 전에 WORK/sheets/final-NN.jpg를 읽으세요. 모든 페이지에서 남은 얼룩, 잘린 텍스트 및 실수로 유지한 항목을 확인하세요. 그런 다음 사용자에게 PDF 경로를 알려주세요. 사용자가 달리 말하지 않는 한 입력 파일 옆에 PDF를 저장합니다(예: <name>_clean.pdf).

좋은 결과의 기준

  • 텍스트 줄이 가장자리에서 가장자리까지 곧고 수평이며, 제본에 가장 가까운 줄도 포함합니다.
  • 종이는 순수한 흰색이고 글자는 진한 검은색이며, 가는 획도 손상되지 않습니다. 큰 어두운 그림은 채우기를 유지합니다.
  • 손가락, 그림자, 이웃 페이지 조각, 얼룩이 없습니다. 측면 여백이 동일하고 모든 페이지에서 텍스트 크기가 같습니다.

실제 사용 시 참고 사항

  • 보정기는 텍스트를 읽으므로, 양쪽 정렬된 줄이 가득한 페이지에서 최상의 성능을 발휘합니다. 줄 모양만 보기 때문에 오른쪽에서 왼쪽으로 쓰는 언어(히브리어, 아랍어)를 포함한 모든 문자 체계에서 작동합니다.
  • 그림 내의 짧은 줄(레이블)은 곡면 맞춤 시 무시되므로, 그림이 페이지를 접지 않습니다.
  • 페이지의 많은 부분을 채우는 어두운 그림은 순진한 색조 보정으로 회색으로 바랠 수 있습니다. tone()은 주변 종이에서 종이 추정치를 낮춰 유지합니다.
  • 페이지 컬이 제본 부근의 몇 글자를 삼켜버린 경우, 사진에는 복구할 내용이 없습니다. 그렇게 말하고 텍스트를 만들어내지 마세요.
  • 두 컬럼 논문: 텍스트 블록은 두 컬럼을 모두 포함합니다. 리뷰 시트에서 제본을 가로질러 맞춰진 줄이 있는지 확인하세요.

관련 스킬