📸 명함 이미지 & OCR 인식 완전 분석

명함 사진을 찍어서 AI가 글자를 읽어내는(OCR) 과정의 모든 단계와 소스코드를 분석합니다.

전체 흐름도

1. 사용자가 + 버튼 클릭 → add_paper_card()
2. 앱 카메라 열림 → 사용자가 명함 사진 촬영
3. 이미지 파일 → callAppBridge() → 네이티브 코드
4. 네이티브에서 서버로 이미지 업로드 (multipart/form-data)
5. 서버: [내부API]/[명함관리]
   ├── 이미지 파일 수신
   ├── OCR 엔진 호출 (아마도 Tesseract 또는 클라우드 OCR API)
   ├── 텍스트 추출: 이름, 직책, 회사명, 전화번호, 주소, 이메일, 팩스
   └── JSON 응답: {name, mobile, org_name, job, addr, email, fax, img_url}
6. 클라이언트가 JSON 수신 → 모달 필드에 자동 채움
7. AI 알림 메시지 표시 (누락된 정보 안내)
요소 ID역할
#paper_img_urlOCR 처리된 이미지의 서버 URL (hidden input)
#paper_img_view_wrap이미지 영역 래퍼 (이미지 있을 때만 표시)
#paper_img_toggle_btn"명함이미지보기" / "명함이미지닫기" 토글 버튼
#paper_img_display실제 이미지 표시 영역 (기본 숨김)
#paper_card_img<img> 요소 — 명함 이미지 표시
#paper_ai_noticeAI 알림 박스 (누락 정보 경고)
#paper_ai_notice_msgAI 알림 메시지 텍스트

이미지 토글 — togglePaperImg()

function togglePaperImg() {
    var imgDisplay = document.getElementById('paper_img_display');
    var btn = document.getElementById('paper_img_toggle_btn');
    if (!imgDisplay) return;

    if (imgDisplay.style.display === 'none') {
        imgDisplay.style.display = 'block';                              // 보이기
        btn.innerHTML = btn.innerHTML.replace('명함이미지보기', '명함이미지닫기');
    } else {
        imgDisplay.style.display = 'none';                               // 숨기기
        btn.innerHTML = btn.innerHTML.replace('명함이미지닫기', '명함이미지보기');
    }
}

OCR 응답 처리 로직

앱에서 촬영한 이미지가 서버에서 OCR 처리된 후, 다음과 같은 JSON 응답이 옵니다:

// 서버 응답 예시 (OCR 결과)
{
    "name": "홍길동",
    "mobile": "010-1234-5678",
    "org_name": "ABC컴퍼니",
    "job": "대표이사",
    "addr": "서울시 강남구 테헤란로 123",
    "email": "hong@abc.com",
    "fax": "02-123-4567",
    "img_url": "[내부경로]/[데이터]/abc123.jpg"
}

// 클라이언트 처리:
if (imgUrl) {
    document.getElementById('paper_img_url').value = imgUrl;  // 숨은 필드에 저장
    document.getElementById('paper_card_img').src = imgUrl;    // 이미지 표시
    imgWrap.style.display = 'block';     // 이미지 래퍼 표시
} else {
    imgWrap.style.display = 'none';      // 이미지 없으면 숨김
}
// 이미지 표시 영역은 접힌 상태로 시작 (imgDisplay.style.display = 'none')

AI 알림 (누락 정보 경고)

OCR이 모든 정보를 완벽하게 읽지 못했을 때 표시되는 경고 메시지입니다:

// 필수 필드 체크
var missing = [];
if (!data.name || data.name.trim() === '') missing.push('이름');
if (!data.mobile || data.mobile.trim() === '') missing.push('휴대전화');
if (!data.org_name || data.org_name.trim() === '') missing.push('소속(기관명)');

if (missing.length > 0) {
    noticeMsgEl.textContent =
        '안녕하세요? IAM AI입니다. 지금 촬영 과정에서 ' +
        missing.join(', ') + ' 등의 정보가 명확하지 않으니 ' +
        '회원님의 최종 확인을 부탁합니다.';
    noticeEl.style.display = 'block';  // 알림 표시
} else {
    noticeEl.style.display = 'none';   // 모든 정보 있으면 숨김
}
💡 초등학생을 위한 비유: OCR은 마치 선생님이 학생의 글씨를 읽는 것과 같아요. 명함 사진이라는 '그림'을 보고 AI 선생님이 거기 적힌 글자를 찾아내는 거예요. 하지만 글씨가 너무 흐리거나 이상한 글씨체면 AI 선생님도 실수할 수 있어서, "이 부분을 다시 확인해 주세요~"라고 친절하게 알려줘요!

이미지 크기 조정 — resize()

function resize(img, maxW, maxH) {
    var width = img.width;
    var height = img.height;
    // 1단계: 너비가 최대치 초과하면 비율 유지하며 축소
    if (width > maxW) {
        ratio = maxW / width;
        $("#card_logo").css("width", maxW);
        $("#card_logo").css("height", height * ratio);
        height = height * ratio;
    }
    // 2단계: 높이가 최대치 초과하면 비율 유지하며 축소
    width = $("#card_logo").width();
    height = $("#card_logo").height();
    if (height > maxH) {
        ratio = maxH / height;
        $("#card_logo").css("height", maxH);
        $("#card_logo").css("width", width * ratio);
    }
}
// 주로 #card_logo (명함 로고 이미지)에 사용됨

앱 카메라 흐름 상세

사용자 클릭 → add_paper_card()
    ↓
callAppBridge('goCardCamera')
    ├── Android: AppScript.goCardCamera() (네이티브 카메라 인텐트)
    └── iOS: webkit.messageHandlers['goCardCamera'].postMessage()
    ↓
네이티브 카메라 열림 → 사용자 촬영
    ↓
이미지 파일 생성 → 네이티브 코드가 HTTP POST로 서버 전송
    ↓
서버 OCR 처리 → JSON 응답
    ↓
WebView로 JSON 콜백 → 클라이언트 JavaScript 수신
    ↓
모달 필드 자동 채움 + AI 알림 표시