PDF to PNG OCR
pdf 파일을 json 으로 파싱해야하는데 하는 방법을 찾아보았다. gpt도 물어보고 claude도 물어보았다. 아래의 값을 받았다.
Mac 에서 기록
# 모든 필요한 도구 한 번에 설치
brew install ghostscript poppler tesseract tesseract-lang imagemagick
# 설치 확인
gs --version
pdftoppm -h
tesseract --list-langs
magick --version
파일생성 예시) pdf_to_ocr_v2.sh
#!/bin/bash
# pdf_to_ocr_advanced.sh
# PDF를 PNG로 변환하고 일본어 OCR을 수행하는 고급 스크립트
# 색상 코드 정의
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
WHITE='\033[0;37m'
BOLD='\033[1m'
NC='\033[0m' # No Color
# 진행 바 함수
show_progress() {
local current=$1
local total=$2
local prefix="$3"
local width=40
local percentage=$((current * 100 / total))
local completed=$((current * width / total))
printf "\r${CYAN}${prefix}${NC} ["
printf "${GREEN}%*s${NC}" $completed | tr ' ' '█'
printf "${WHITE}%*s${NC}" $((width - completed)) | tr ' ' '░'
printf "] ${BOLD}%d%%${NC} (${YELLOW}%d${NC}/${BLUE}%d${NC})" $percentage $current $total
}
# 스피너 함수
spinner() {
local pid=$1
local message="$2"
local delay=0.1
local spinstr='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'
while kill -0 $pid 2>/dev/null; do
for i in $(seq 0 $((${#spinstr}-1))); do
if ! kill -0 $pid 2>/dev/null; then
break
fi
printf "\r${CYAN}%s${NC} ${spinstr:$i:1} " "$message"
sleep $delay
done
done
printf "\r${GREEN}%s${NC} ✅ \n" "$message"
}
# 에러 메시지 함수
error_msg() {
echo -e "${RED}❌ 오류:${NC} $1"
}
# 성공 메시지 함수
success_msg() {
echo -e "${GREEN}✅ 성공:${NC} $1"
}
# 정보 메시지 함수
info_msg() {
echo -e "${BLUE}ℹ️ 정보:${NC} $1"
}
# 경고 메시지 함수
warn_msg() {
echo -e "${YELLOW}⚠️ 경고:${NC} $1"
}
# 헤더 출력 함수
print_header() {
echo -e "${BOLD}${PURPLE}"
echo "╔══════════════════════════════════════════════════════════════╗"
echo "║ PDF to OCR Converter ║"
echo "║ Advanced Version ║"
echo "╚══════════════════════════════════════════════════════════════╝"
echo -e "${NC}"
}
# 필요한 도구 확인 함수
check_dependencies() {
local missing_tools=()
info_msg "필요한 도구들을 확인하는 중..."
if ! command -v magick &> /dev/null && ! command -v convert &> /dev/null; then
missing_tools+=("ImageMagick")
fi
if ! command -v tesseract &> /dev/null; then
missing_tools+=("Tesseract")
fi
if ! command -v gs &> /dev/null; then
missing_tools+=("Ghostscript")
fi
if [ ${#missing_tools[@]} -ne 0 ]; then
error_msg "다음 도구들이 설치되지 않았습니다:"
for tool in "${missing_tools[@]}"; do
echo " - $tool"
done
echo ""
echo "설치 명령어:"
echo " brew install imagemagick ghostscript tesseract tesseract-lang poppler"
exit 1
fi
# 일본어 언어팩 확인
if ! tesseract --list-langs | grep -q "jpn"; then
warn_msg "일본어 언어팩이 설치되지 않았을 수 있습니다."
echo "설치 명령어: brew install tesseract-lang"
fi
success_msg "모든 필요한 도구가 설치되어 있습니다."
}
# 메인 스크립트 시작
main() {
print_header
PDF_FILE="$1"
if [ -z "$PDF_FILE" ]; then
error_msg "PDF 파일을 지정해주세요."
echo "사용법: $0 파일명.pdf"
exit 1
fi
if [ ! -f "$PDF_FILE" ]; then
error_msg "$PDF_FILE 파일이 존재하지 않습니다."
exit 1
fi
# 의존성 확인
check_dependencies
echo ""
# PDF 정보 확인
info_msg "PDF 파일 분석 중..."
file_size=$(ls -lh "$PDF_FILE" | awk '{print $5}')
echo " 📄 파일명: $PDF_FILE"
echo " 📏 파일크기: $file_size"
# 페이지 수 확인
if command -v pdfinfo &> /dev/null; then
total_pages=$(pdfinfo "$PDF_FILE" 2>/dev/null | grep "Pages:" | awk '{print $2}')
if [ -n "$total_pages" ]; then
echo " 📃 총 페이지: $total_pages"
fi
fi
echo ""
# 기존 파일 정리 확인
if ls page_*.png output_*.txt &> /dev/null; then
warn_msg "기존 변환 파일들이 발견되었습니다."
read -p "삭제하고 계속하시겠습니까? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
rm -f page_*.png output_*.txt processed_*.png
success_msg "기존 파일들을 삭제했습니다."
else
info_msg "기존 파일들을 유지합니다."
fi
echo ""
fi
# PDF to PNG 변환
echo -e "${BOLD}${BLUE}=== 1단계: PDF에서 PNG 추출 ===${NC}"
# ImageMagick 버전 확인
if command -v magick &> /dev/null; then
CONVERT_CMD="magick"
else
CONVERT_CMD="convert"
fi
info_msg "변환을 시작합니다..."
# 백그라운드에서 변환 실행
$CONVERT_CMD -density 300 -quality 100 "$PDF_FILE" page_%03d.png &
convert_pid=$!
# 스피너로 진행 상황 표시
spinner $convert_pid "PDF 변환 중 (시간이 걸릴 수 있습니다)"
# 변환 결과 확인
png_count=$(ls page_*.png 2>/dev/null | wc -l | tr -d ' ')
if [ "$png_count" -eq 0 ]; then
warn_msg "ImageMagick 변환 실패. pdftoppm으로 재시도..."
if command -v pdftoppm &> /dev/null; then
pdftoppm -png -r 300 "$PDF_FILE" page &
convert_pid=$!
spinner $convert_pid "pdftoppm으로 변환 중"
# 파일명 형식 통일 (page-001.png → page_001.png)
for file in page-*.png; do
if [ -f "$file" ]; then
new_name=$(echo "$file" | sed 's/-/_/')
mv "$file" "$new_name"
fi
done
png_count=$(ls page_*.png 2>/dev/null | wc -l | tr -d ' ')
else
error_msg "pdftoppm도 설치되지 않았습니다."
echo "설치 명령어: brew install poppler"
exit 1
fi
fi
if [ "$png_count" -eq 0 ]; then
error_msg "PNG 추출에 완전히 실패했습니다."
exit 1
fi
success_msg "$png_count 개의 PNG 파일을 추출했습니다."
echo ""
# OCR 처리
echo -e "${BOLD}${BLUE}=== 2단계: OCR 텍스트 추출 ===${NC}"
success_count=0
total_count=0
failed_files=()
# 파일 목록을 배열로 만들기
png_files=(page*.png)
total_files=${#png_files[@]}
for file in "${png_files[@]}"; do
if [ -f "$file" ]; then
filename=$(basename "$file" .png)
total_count=$((total_count + 1))
# 진행률 표시
show_progress $total_count $total_files "OCR 처리"
echo ""
echo -n " 🔍 처리 중: $file ... "
# 이미지 전처리
$CONVERT_CMD "$file" \
-colorspace Gray \
-normalize \
-sharpen 0x1 \
-contrast-stretch 0 \
"processed_$filename.png" 2>/dev/null
# OCR 실행
if tesseract "processed_$filename.png" "output_$filename" -l jpn --psm 6 --oem 3 2>/dev/null; then
echo -e "${GREEN}✅${NC}"
success_count=$((success_count + 1))
# 텍스트 파일 크기 확인
if [ -f "output_$filename.txt" ]; then
txt_size=$(wc -c < "output_$filename.txt" | tr -d ' ')
echo " 📝 추출된 텍스트: ${txt_size}자"
fi
else
echo -e "${RED}❌${NC}"
failed_files+=("$file")
fi
# 임시 파일 삭제
rm -f "processed_$filename.png"
# 잠시 대기 (너무 빨리 지나가지 않도록)
sleep 0.1
fi
done
echo ""
echo ""
# 최종 결과 출력
echo -e "${BOLD}${PURPLE}=== 📊 최종 결과 요약 ===${NC}"
echo ""
success_rate=$((success_count * 100 / total_count))
echo -e "📄 ${BOLD}처리된 파일:${NC} $total_count 개"
echo -e "✅ ${BOLD}${GREEN}성공:${NC} $success_count 개"
echo -e "❌ ${BOLD}${RED}실패:${NC} $((total_count - success_count)) 개"
echo -e "📈 ${BOLD}성공률:${NC} ${success_rate}%"
# 성공률에 따른 이모지
if [ $success_rate -ge 90 ]; then
echo -e "🎉 ${GREEN}훌륭합니다!${NC}"
elif [ $success_rate -ge 70 ]; then
echo -e "👍 ${YELLOW}양호합니다!${NC}"
elif [ $success_rate -ge 50 ]; then
echo -e "😐 ${YELLOW}보통입니다.${NC}"
else
echo -e "😞 ${RED}개선이 필요합니다.${NC}"
fi
echo ""
# 실패한 파일들 표시
if [ ${#failed_files[@]} -gt 0 ]; then
warn_msg "실패한 파일들:"
for failed_file in "${failed_files[@]}"; do
echo " - $failed_file"
done
echo ""
fi
# 생성된 파일들 정보
if [ $success_count -gt 0 ]; then
info_msg "생성된 텍스트 파일들:"
txt_files=(output_*.txt)
display_count=5
for ((i=0; i<${#txt_files[@]} && i<display_count; i++)); do
file="${txt_files[$i]}"
if [ -f "$file" ]; then
size=$(wc -c < "$file" | tr -d ' ')
echo " 📝 $file (${size}자)"
fi
done
if [ ${#txt_files[@]} -gt $display_count ]; then
echo " ... 그리고 $((${#txt_files[@]} - display_count))개 더"
fi
echo ""
info_msg "모든 텍스트를 합치려면: cat output_*.txt > 전체텍스트.txt"
fi
echo ""
echo -e "${BOLD}${GREEN}🎊 모든 작업이 완료되었습니다! 🎊${NC}"
}
# 스크립트 실행
main "$@"
스크립트 실행권한주기chmod +x pdf_to_ocr_v2.sh
실행방법
./pdf_to_ocr_v2.sh ‘변환하고 싶은.pdf’
./pdf_to_ocr_v2.sh orc.pdf
실행화면 예시
